Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React Firebase:为什么页面在第一次加载时失败,但在刷新时正确加载?_Reactjs_Firebase_Firebase Authentication - Fatal编程技术网

Reactjs 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 "

我有一个react项目,它正在从firebase后端提取数据。加载呈现我的
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组件。没有