繁体   English   中英

React-Firebase:为什么页面在第一次加载时失败,但在刷新时加载正确?

[英]React-Firebase: Why does page fail on first load, but then loads properly on refresh?

我有一个从 firebase 后端提取数据的 React 项目。 当我加载呈现我的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

因为您在第一页加载时尚未登录。 当你第一次在你的应用程序上加载这个组件时,你的浏览器仍然没有使用 Firebase 检查你是否登录,所以在第一次渲染时currentUser将是未定义的。

不过,这很容易解决。 例如,有一个 state 变量,假设userIsLoggedIn跟踪登录状态,它开始时是未定义的。 onAuthStateChanged的回调中,您可以将其设置为 true 或 false,具体取决于身份验证是否成功。

然后,如果 userIsLoggedIn 未定义,您可以显示一条消息,如“Authenticating...”,如果它是 false,您将显示一个登录表单,如果它是 true,您将继续使用您的应用程序,知道您使用的是正确登录和 currentUser.uid有一个值。

顺便说一句,这是关于此的官方文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM