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

问题描述 投票:0回答:2

我有一个 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
reactjs firebase firebase-authentication
2个回答
1
投票

因为您在首页加载时尚未登录。当您第一次在应用程序上加载此组件时,您的浏览器仍然没有使用 Firebase 检查您是否登录,因此第一次渲染

currentUser
将是未定义的。

不过这是一个简单的解决方法。举个例子,只有一个状态变量,比如

userIsLoggedIn
跟踪登录状态,该变量一开始是未定义的。在
onAuthStateChanged
的回调中,您可以将其设置为 true 或 false,具体取决于身份验证是否成功。

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

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


0
投票

请问这个问题有答案吗?我面临类似的问题。我需要单击刷新按钮才能显示页面。当我单击侧边栏菜单图标 > URL 已经更改 > 但页面仍然不会显示。我每次都需要点击刷新...

© www.soinside.com 2019 - 2024. All rights reserved.