React Component не будет отображать новое состояние даже после повторного рендеринга - PullRequest
0 голосов
/ 22 октября 2019

По существу, у меня возникла проблема, когда компонент реагирования не отображает массив из своего состояния. Состояние содержит нужный мне массив, и метод рендеринга вызывается снова, когда массив var заполняется, но ничего не отображается.

Я попытался предварительно заполнить массив состояний фиктивными данными, и он отрисовывается очень хорошо. Но когда я использую функцию для заполнения массива, страница обновляется и ничего не отображается. Если я проверяю состояние компонента, у него есть данные, которые я хочу, но метод визуализации компонента, кажется, не хочет его отображать.

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 () вызывается, но метод рендеринга не показывает данные.

Если я предварительно заполню данные фиктивными символами и закомментирую getScopes () в componentDidMount (), как показано ниже, и сохраню всев остальном то же самое, фиктивные символы отображаются нормально.

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 (), как только компонент монтируется,но вместо этого ничего не обувь. Хотя я с помощью инструментов разработчика подтвердил, что данные существуют в массиве состояний областей действия, рендер не показывает их.

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Внутри getScopes вы заполняете tempScopes в then Обещания, которое выполняется асинхронно . Но под ним вы также немедленно вызываете setState, что означает, что во время вызова setState, tempScopes массив все еще пуст. Вы должны переместить вызов на setState также внутри then. Как то так:

       .then((querySnapshot) => {
            querySnapshot.forEach(function(doc) {
                tempScopes.push(doc.data().address);
            })
            this.setState({scopes:tempScopes});
        })
0 голосов
/ 22 октября 2019

Как обычно, ответ пришел ко мне через несколько минут после публикации. Я думаю, что проблемы возникли из-за связывания этого в функции getScopes. Этот код исправил проблему.

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);
        });
}
...