Компонент теряет данные из состояний при перезагрузке - PullRequest
0 голосов
/ 13 октября 2018

Я создаю базовую настройку формы, но мне нужно получить данные о пользователях до изменения, чтобы они могли редактировать эти данные.На первой странице загрузки все работает как надо, но как только я обновляю страницу (F5), я получаю сообщение об ошибке: Unhandled Rejection (TypeError): Cannot read property 'userFirstName' of null.Идентификатор пользователя не захватывается во второй раз, когда я обновляю страницу.Если я покидаю страницу, перехожу на другую страницу и возвращаюсь, она загружается снова, как и должна.Как мне заставить страницу всегда перехватывать данные при обновлении страницы?

Я использую React.js, Firebase и React-router

Settings.js:

import React, { Component } from 'react';
import fire from '../../config/Fire.js';

export default class Settings extends Component {
    constructor(props) {
        super(props)
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.update = this.update.bind(this);

        this.userDatabase = fire.database().ref().child('users');
        this.state = {
            userId: this.props.user.uid,
            userFirstName: '',
        };
      }

        componentWillMount(){
                fire.database().ref('/users/' + this.state.userId).once('value').then(function(snapshot) {
                    var first_name = (snapshot.val().userFirstName);

                    this.setState({
                    userFirstName: first_name,
                    })
                }.bind(this));
        }

      handleChange(e) {
          this.setState({ [e.target.name]: e.target.value });
      }

      handleSubmit(e) {
          e.preventDefault();
      }

      update(e){
          e.preventDefault();
          //update here
          fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).then((u)=>{ this.props.history.push('/about') }).catch((error) => {
              alert(error);
              });
      }

    render() {
        return (
            <div className="m-container">
                <h1>Hello, {this.state.userFirstName}</h1>
                <hr/>
                <p>Here are your settings details:</p>
                <label for="first-name">First Name: </label>
                <br/>
                <input 
                    value={this.state.userFirstName} 
                    onChange={this.handleChange} 
                    type="text" 
                    name="first-name" 
                    id="first-name" 
                    placeholder={this.state.userFirstName}
                    />
                <br/>
                <br/>
                <button 
                    type="submit" 
                    className="m-btn" 
                    onClick={this.signup}>Submit</button>
                &nbsp;
            </div>
        );
    }
}

Index.js (Маршрутизация для передачи userId в качестве реквизита на страницы):

import React, { Component } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';

import Home from './main/Home';
import About from './main/About';
import LoginContainer from '../components/LoginContainer';
import RegisterContainer from '../components/RegisterContainer';
import Resolved from './main/Resolved';
import Settings from './main/Settings';

export default class Routes extends Component {

    render() {
        return (
        <Switch>
            <Route path="/" exact component={Home} />
            <Route path="/about" exact component={About} />
            <Route path="/register" render={()=> <RegisterContainer user={this.props.user} />} />
            <Route path="/login" render={()=> <LoginContainer user={this.props.user} />} />

            <Route path="/resolved" exact render={()=>(
                this.props.user ? (<Resolved user={this.props.user} />) : 
                (alert("You must log in to visit this page."), (<Redirect to="/login"/>))
            )} />
            <Route path="/account/settings" exact render={()=>(
                this.props.user ? (<Settings user={this.props.user} />) : 
                (alert("You must log in to visit this page."), (<Redirect to="/login"/>))
            )} />


        </Switch>
        );
    }

};

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Решено следующее: https://javebratt.com/firebase-user-undefined/

Выполнен асинхронный вызов, поскольку в течение некоторого момента перед извлечением данных uid был нулевым, и произошла ошибка.Просто пришлось ждать загрузки данных, прежде чем ошибка исчезнет.Также я получаю UID новым способом через fire.auth().currentUser.uid.

Код, который я изменил в Settings.js:

  componentDidMount(){
    // Asynchronous call fixes uid being null on reload
    fire.auth().onAuthStateChanged( user => {
        if (user) { 
            fire.database().ref('/users/' + fire.auth().currentUser.uid).once('value').then(function(snapshot) {
                this.setState({
                  userFirstName: (snapshot.val().userFirstName),
                  userLastName: (snapshot.val().userLastName),
                  userEmail: (snapshot.val().userEmail),
                  userPhone: (snapshot.val().userPhone),
                  userAddress: (snapshot.val().userAddress),
                  userZip: (snapshot.val().userZip),
                  userProfilePicUrl: (snapshot.val().userProfilePicUrl)
                })
              }.bind(this));          
         }
      });
0 голосов
/ 13 октября 2018

вы должны вызывать ваше firebase соединение в componentDidMount, но не в конструкторе.Вы можете прочитать подробности, когда использовать React Lifecycles.Несмотря на то, что он устарел (не реагирует на 16 статей), это отличный ресурс.https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1

class App extends React.Component {
  constructor() {}
  componentDidMount() {
    // firebase call
    // do setState
  }

  render() {
    return <div></div>
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...