【问题标题】:React Component won't render new state even after rerender即使在重新渲染之后,React 组件也不会渲染新状态
【发布时间】:2020-02-18 00:03:41
【问题描述】:

基本上我遇到了一个问题,即反应组件不会呈现来自其状态的数组。 state 确实包含我想要的数组,并且当数组 var 被填充时再次调用 render 方法,但没有任何显示。

我已经尝试用虚拟数据预填充状态数组,它渲染得很好。但是当我使用一个函数来填充数组时,页面会更新并且什么都没有显示。如果我检查组件的状态,它有我想要的数据,但组件的渲染方法似乎不想显示它。

import React, { Component } from 'react';
import { withAuthorization } from '../Session';
import { withFirebase } from '../Firebase'; //
import 'firebase/firestore';

const Home = () => (
  <div>
    <h1>Home Page</h1>
    <p>Signed in users only</p>
    <hr />

    <h1>Available Scopes</h1>
    <ScopeRender />

  </div>
);


class ScopeRenderBase extends Component {

    constructor(props) {
        super(props);
        this.state = {
            scopes: []
        }
        //this.componentDidMount = this.componentDidMount.bind(this);
    }

    async componentDidMount() {
        await this.getScopes();
        //console.log(this.state.scopes);
    }

    componentDidUpdate() {
        //console.log(this.state.scopes);
    }

    getScopes() {
        let tempScopes = [];
        this.props.firebase.db.collection("scopes").where("status", "==", 1).get()
            .then( (querySnapshot) => {
                querySnapshot.forEach(function(doc) {
                    tempScopes.push(doc.data().address);
                })
            })
            .catch(function(error) {
                console.log("Error getting documents: ", error);
            });

        //console.log(tempScopes);
        this.setState({ 
            scopes: tempScopes
        });
    }

    render() {
        const displayPosts = this.state.scopes.map((scope, index) =>
            <li key={index}>{scope}</li>
        );
        console.log(this.state.scopes);
        return(
            <div>
                <div>{this.state.scopes}</div>
                <ul>{displayPosts}</ul>
            </div>
        );
    }

}

const ScopeRender = withFirebase(ScopeRenderBase);

const condition = authUser => !!authUser;

export default withAuthorization(condition)(Home);
export { ScopeRender };

使用此代码,状态包含调用函数 getScopes() 后我想要的数据(范围),但渲染方法不显示数据。

如果我用虚拟字符预填充数据并像下面这样在 componentDidMount() 中注释掉 getScopes() 并保持其他所有内容相同,则虚拟字符显示得很好。

class ScopeRenderBase extends Component {

    constructor(props) {
        super(props);
        this.state = {
            scopes: ['a','b','c']
        }
        //this.componentDidMount = this.componentDidMount.bind(this);
    }

    async componentDidMount() {
        //await this.getScopes();
        //console.log(this.state.scopes);
    }

我希望代码在组件安装后立即调用 getScopes() 后显示来自组件状态的数组的项目符号列表,但没有鞋子。我已经通过开发工具确认数据确实存在于范围状态数组中,但渲染并没有显示它。

【问题讨论】:

    标签: reactjs components state


    【解决方案1】:

    getScopes 中,您将tempScopes 填充到Promise 的then 中,该Promise 是异步运行的。 但是在它下面你也立即调用setState,这意味着在你调用setState时,tempScopes数组仍然是空的。 您应该将呼叫转移到 setState 也在 then 内。像这样的:

           .then((querySnapshot) => {
                querySnapshot.forEach(function(doc) {
                    tempScopes.push(doc.data().address);
                })
                this.setState({scopes:tempScopes});
            })
    

    【讨论】:

      【解决方案2】:

      像往常一样,我在发布后不久就得到了答案。我认为问题源于 getScopes 函数中 this 的绑定。这段代码解决了这个问题。

      getScopes() {
          let tempScopes = [];
          this.props.firebase.db.collection("scopes").where("status", "==", 1).get()
              .then( (querySnapshot) => (
                  querySnapshot.forEach( (doc) => (
                      this.setState((prevState) => ({
                          scopes: [ ...this.state.scopes, doc.data().address ]
                      }))
                  ))
              ))
              .catch(function(error) {
                  console.log("Error getting documents: ", error);
              });
      }
      

      【讨论】:

        猜你喜欢
        • 2022-11-04
        • 1970-01-01
        • 2021-05-19
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 2019-08-09
        • 1970-01-01
        • 2019-06-17
        相关资源
        最近更新 更多