【问题标题】:Data not displaying in on load - only after page refresh加载时不显示数据 - 仅在页面刷新后
【发布时间】:2018-04-26 14:35:06
【问题描述】:

我是 React JS 的新手,我一直在学习一些教程来了解它。

以下代码取自有关 cmets 现已关闭的教程,我正在尝试解决它的问题。

当我运行应用程序时,Firebase 中的数据不显示,我也无法将项目添加到列表中 - 用户似乎没有发生任何事情,尽管我可以看到 Firebase 中添加的数据。如果我重新加载页面,一切正常。

我猜这与componentDidMount有关,据我所知,它只会在页面第一次加载时调用,所以如果用户没有登录,数据就不会加载,也不会是,即使在用户登录后 - 对吗?

谁能帮我在用户登录后立即加载数据,而不是要求刷新页面?

 import React, { Component } from 'react';
// import logo from './logo.svg';
import './App.css';
import firebase, { auth, provider } from './firebase.js';

class App extends Component {
  constructor() {
    super();
    this.state = {
      currentItem: '',
      username: '',
      datetime: '',
      items: [],
      user: null,
      profileImg: ''
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
  }
  handleChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }
  login() {
      auth.signInWithPopup(provider)
          .then((result) => {
              const user = result.user;
              this.setState({
                  user
              });
          });

  }
  logout() {
      auth.signOut()
          .then(() => {
              this.setState({
                  user: null
              });
          });
  }
  handleSubmit(e) {
    e.preventDefault();
    const itemsRef = firebase.database().ref('items');
    const item = {
        title: this.state.currentItem,
        user: this.state.user.displayName || this.state.user.email,
        profileImg: this.state.user.photoURL
    }
    itemsRef.push(item);
    this.setState({
      currentItem: '',
      username: '',
      profileImg: this.state.user.photoURL
    });
  }
  componentDidMount() {

    const itemsRef = firebase.database().ref('items');

    itemsRef.on('value', (snapshot) => {
      let items = snapshot.val();
      let newState = [];
      for (let item in items) {
        newState.push({
          id: item,
          title: items[item].title,
          user: items[item].user,
          profileImg: items[item].profileImg
        });
      }
      this.setState({
        items: newState
      });
    });

    auth.onAuthStateChanged((user) => {
        if (user) {
            this.setState({ user });
        }
    });
  }

  removeItem(itemId) {
    const itemRef = firebase.database().ref(`/items/${itemId}`);
    itemRef.remove();
  }
  render() {
      return (
          <div className='app'>
            <header>
              <div className="wrapper">
                <h1></h1>
                  {this.state.user ?
                      <button onClick={this.logout}>Logout</button>
                      :
                      <button onClick={this.login}>Log In</button>
                  }
              </div>
            </header>

              {this.state.user ?
                  <div>
                    <div className='user-profile'>
                      <img src={this.state.user.photoURL} alt={this.state.user.displayName} />
                    </div>
                    <div className='container'>
                        <section className='display-item'>
                            <div className="wrapper">
                                <ul>
                                    {this.state.items.reverse().map((item) => {
                                        return (
                                            <li key={item.id}>
                                                <h3>{item.title}</h3>
                                                <p>brought by: {item.user}
                                                    {item.user === this.state.user.displayName || item.user === this.state.user.email ?
                                                        <button onClick={() => this.removeItem(item.id)}>Remove Item</button> : null}

                                                    <img src={item.profileImg} alt={this.state.user.displayName} className={"profileImg"} />

                                                </p>
                                            </li>
                                        )
                                    })}
                                </ul>
                            </div>
                        </section>
                      <section className='add-item'>
                        <form onSubmit={this.handleSubmit}>
                          <input type="text" name="username" placeholder="What's your name?" onChange={this.handleChange} value={this.state.user.displayName || this.state.user.email} disabled />
                          <input type="text" name="currentItem" placeholder="What are you bringing?" onChange={this.handleChange} value={this.state.currentItem} />
                          <button>Add Item</button>
                        </form>
                      </section>
                    </div>
                    </div>
                  :
                  <div className='wrapper'>
                    <p>You must be logged in to see this page.</p>
                  </div>
              }

          </div>

      );
  }
}

export default App;

然后是我拥有的firebase.js:

import firebase from 'firebase'

var config = {
    apiKey: "xxxxxxxxxxxx",
    authDomain: "xxxxxxxxxxxx.firebaseapp.com",
    databaseURL: "https://xxxxxxxxxxxx.firebaseio.com",
    projectId: "xxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxx.appspot.com",
    messagingSenderId: "xxxxxxxxxxxx"
};

firebase.initializeApp(config);

export const provider = new firebase.auth.GoogleAuthProvider();
export const auth = firebase.auth();

export default firebase;

我很确定原教程中存在这个问题,可以在https://css-tricks.com/firebase-react-part-2-user-authentication/查看。

任何帮助将不胜感激。

谢谢,

约翰。

【问题讨论】:

  • ./firabe.js 中有什么?能发一下吗?
  • 我已经添加进去了,谢谢。

标签: javascript reactjs firebase firebase-realtime-database firebase-authentication


【解决方案1】:

也许只是将您的 firebase 调用拉到一个单独的函数中,并在用户登录后调用它?:

login() {
  auth.signInWithPopup(provider)
      .then((result) => {
          this.callFirebaseFunction()
          const user = result.user;
          this.setState({
              user
          });
      });

}

【讨论】:

    【解决方案2】:

    您应该使用观察者来跟踪用户的登录状态。那就是onAuthStateChanged。所以代码将是,如果用户已登录,并且不等于 null 然后检索数据。你的代码应该是:

    import { getAuth, onAuthStateChanged } from "firebase/auth";
    
    const auth = getAuth();
    onAuthStateChanged(auth, (user) => {
      if (user) {
        // User is signed in, see docs for a list of available properties
        // https://firebase.google.com/docs/reference/js/firebase.User
        const uid = user.uid;
        // ...
      } else {
        // User is signed out
        // ...
      }
    });

    关注官方文档以获得完美结果:https://firebase.google.com/docs/auth/web/manage-users

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      相关资源
      最近更新 更多