数据未在加载时显示 - 仅在页面刷新后显示

时间:2017-11-13 19:46:13

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

我是React JS的新手,我已经通过一些教程来了解它。

以下代码取自现已关闭评论的教程,我试图用它来解决问题。

当我运行应用时,来自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/查看。

非常感谢任何帮助。

谢谢,

约翰。

1 个答案:

答案 0 :(得分:0)

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

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

}