Reactjs React Firebase:为什么页面在第一次加载时失败,但在刷新时正确加载?
我有一个react项目,它正在从firebase后端提取数据。加载呈现我的Reactjs React Firebase:为什么页面在第一次加载时失败,但在刷新时正确加载?,reactjs,firebase,firebase-authentication,Reactjs,Firebase,Firebase Authentication,我有一个react项目,它正在从firebase后端提取数据。加载呈现我的GigRegister组件的页面时,出现以下错误: Unhandled Rejection (TypeError): Cannot read property 'uid' of null ..但当我刷新页面时,它会按应有的方式加载。你知道为什么吗?以下是我的GigRegister组件的代码: import React from "react"; import Header from "
GigRegister
组件的页面时,出现以下错误:
Unhandled Rejection (TypeError): Cannot read property 'uid' of null
..但当我刷新页面时,它会按应有的方式加载。你知道为什么吗?以下是我的GigRegister
组件的代码:
import React from "react";
import Header from "./Header";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import axios from "axios";
import * as firebase from 'firebase'
import { auth } from 'firebase/app'
import {Link} from 'react-router-dom'
import UniqueVenueListing from './UniqueVenueListing'
class GigRegister extends React.Component {
constructor() {
super();
this.state = {
name: "",
venue: "",
time: "",
date: "",
genre: "",
tickets: "",
price: "",
userDetails:{},
filterGigs:[]
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this)
}
handleChange(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
handleClick(){
console.log('handle click reached')
auth().signOut().then(() => {
console.log('Successfully signed out')
})
.catch(err => {
console.log(err)
})
}
authListener(){
auth().onAuthStateChanged((user)=>{
if(user){
this.setState({
userDetails: user
})
axios.get("https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings")
.then(res=> {
let filteredGigs = res.data
.filter(gig => {
return gig.user === this.state.userDetails.uid
})
this.setState({
filterGigs: filteredGigs
})
})
} else {
this.setState({
userDetails: null
})
console.log('no user signed in')
}
})
}
componentDidMount(){
this.authListener()
}
handleSubmit(e) {
let user = auth().currentUser.uid
const gigData = {
name: this.state.name,
venue: this.state.venue,
time: this.state.time,
date: this.state.date,
genre: this.state.genre,
tickets: this.state.tickets,
price: this.state.price,
user:user
};
auth().currentUser.getIdToken().then(function(token) {
axios("http://localhost:5000/gig-fort/us-central1/api/createGigListing", {
method: "POST",
headers: {
"content-type": "application/json",
"Authorization": "Bearer "+token,
},
data: gigData,
})
})
.then((res) => {
console.log(res);
this.props.history.push('/Homepage')
})
.catch((err) => {
console.error(err);
});
}
render() {
return (
<div className="gig-register">
<Header />
<div className = 'heading-container'>
<h1>Venue Dashboard</h1> <br></br>
{
this.state.userDetails ?
<h3>You are signed in as {this.state.userDetails.email}</h3>
:
null
}
<div className = 'gig-reg-buttons'>
{
this.state.userDetails ?
<Button onClick = {this.handleClick}>Sign out </Button>
:
<Link to = '/' style={{ textDecoration: "none" }}>
<Button>Sign In</Button>
</Link>
}
<Link to="/Homepage" style={{ textDecoration: "none" }}>
<Button>Go to gig listings</Button>
</Link>
</div>
</div>
<div className = 'handle-gigs'>
<div className = 'reg-gig-input'>
<form onSubmit={this.handleSubmit}>
<h3>Register a gig</h3>
<br></br>
<TextField
placeholder="Event name"
defaultValue="Event name"
id="name"
name="name"
onChange={this.handleChange}
/>
<TextField
placeholder="Time"
defaultValue="Time"
type="time"
label="Enter start time"
id="time"
name="time"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={this.handleChange}
/>
<TextField
id="date"
label="Select date"
type="date"
defaultValue="2017-05-24"
InputLabelProps={{
shrink: true,
}}
onChange={(e) => {
this.setState({ date: e.target.value });
}}
/>
<TextField
placeholder="Genre"
defaultValue="Genre"
id="genre"
name="genre"
onChange={this.handleChange}
/>
<TextField
placeholder="Tickets"
defaultValue="Tickets"
id="tickets"
name="tickets"
onChange={this.handleChange}
/>
<TextField
placeholder="Price"
defaultValue="Price"
id="price"
name="price"
onChange={this.handleChange}
/>
<Button type="submit">Submit</Button>
</form>
</div>
<div className = 'manage-gigs'>
<h3 className = 'manage-gig'>Manage your gigs</h3>
<br></br>
{ this.state.userDetails ?
<UniqueVenueListing gigList = {this.state.filterGigs}/>
:
<h2>no gigs to show</h2>
}
</div>
</div>
</div>
);
}
}
export default GigRegister
从“React”导入React;
从“/Header”导入标题;
从“@material ui/core/TextField”导入TextField;
从“@物料界面/核心/按钮”导入按钮;
从“axios”导入axios;
从“firebase”导入*作为firebase
从“firebase/app”导入{auth}
从“react router dom”导入{Link}
从“./UniqueVenueListing”导入UniqueVenueListing
类GigRegister扩展了React.Component{
构造函数(){
超级();
此.state={
姓名:“,
地点:“,
时间:“,
日期:“,
体裁:“,
门票:“,
价格:“,
用户详细信息:{},
filterGigs:[]
};
this.handleSubmit=this.handleSubmit.bind(this);
this.handleChange=this.handleChange.bind(this);
this.handleClick=this.handleClick.bind(this)
}
手变(e){
这是我的国家({
[e.target.name]:e.target.value,
});
}
handleClick(){
console.log('handle click reach')
auth().signOut()。然后(()=>{
console.log('已成功注销')
})
.catch(错误=>{
console.log(错误)
})
}
authListener(){
auth().onAuthStateChanged((用户)=>{
如果(用户){
这是我的国家({
用户详细信息:用户
})
axios.get(“https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings")
。然后(res=>{
设filteredGigs=res.data
.filter(gig=>{
return gig.user===this.state.userDetails.uid
})
这是我的国家({
filterGigs:filteredigs
})
})
}否则{
这是我的国家({
userDetails:null
})
console.log('没有用户登录')
}
})
}
componentDidMount(){
this.authListener()
}
handleSubmit(e){
让user=auth().currentUser.uid
常量数据={
名称:this.state.name,
地点:这个州,地点,
时间:这个州,时间,
日期:this.state.date,
类型:this.state.genre,
票:这个州的票,
普莱斯:这个州普莱斯,
用户:用户
};
auth().currentUser.getIdToken().then(函数(令牌){
axios(“http://localhost:5000/gig-fort/us-central1/api/createGigListing“{
方法:“张贴”,
标题:{
“内容类型”:“应用程序/json”,
“授权”:“持票人”+代币,
},
数据:gigData,
})
})
。然后((res)=>{
控制台日志(res);
this.props.history.push(“/Homepage”)
})
.catch((错误)=>{
控制台错误(err);
});
}
render(){
返回(
场馆仪表板
{
this.state.userDetails?
您已以{this.state.userDetails.email}身份登录
:
无效的
}
{
this.state.userDetails?
退出
:
登录
}
转到演出列表
登记演出
{
this.setState({date:e.target.value});
}}
/>
提交
管理你的演出
{this.state.userDetails?
:
没有演出
}
);
}
}
导出默认寄存器
因为您在第一次加载页面时还没有登录。当您第一次在应用程序上加载此组件时,如果您登录或未登录,您的浏览器仍然没有与Firebase进行检查,因此第一次渲染currentUser
将被取消定义
不过这是一个简单的解决办法。例如,只要有一个状态变量,比如说userIsLoggedIn
跟踪登录状态,它将以未定义开始。在onAuthStateChanged中的回调上,您可以将其设置为true或false,具体取决于身份验证是否成功
然后,如果userIsLoggedIn未定义,您可以显示类似“Authentication…”的消息,如果为false,则显示登录表单,如果为true,则继续使用应用程序,知道您使用的已正确登录,并且currentUser.uid具有值
顺便说一句,这是关于这个问题的答案。谢谢你的回答。这是否意味着我必须将身份验证侦听器从GigRegister组件移动到登录组件?因为目前它们是两个独立的东西。@Josh Simon您本身不必这样做,只要您处理currentUser在GigRegister中可能未定义的事实。不过,拥有一个Auth组件可能会更简单、更干净,根据身份验证状态,该组件将呈现一个加载指示器组件、一个登录组件或GigRegister组件。没有