node.js - 加载数据后响应更新组件

标签 node.js reactjs firebase redux google-cloud-firestore

所以我有一个显示 firestore 中的类别的组件,该组件第一次不显示任何内容,但是当我再次单击导航栏按钮时,它确实显示了 firestore 中存储的数据。

这是组件文件:

import * as React from "react";
import Category from "./Category";
import connect from "react-redux/es/connect/connect";
import {getCategories} from "../reducers/actions/categoryAction";

class CategoriesList extends React.Component{
    constructor(props) {
        super(props);
        this.state = ({
            categoriesList: [{}]
        })
    }

    componentWillMount() {
        this.props.getCategories();
        this.setState({categoriesList: this.props.categories});
        this.forceUpdate();
    }

    render() {
        return (
            <div className={'container categories'}>
                <div className={'row center'} onClick={() => this.props.history.push('/addcategories')}>
                    <div className={'col s24 m12'}>
                        <p>Create New Category</p>
                    </div>
                </div>

                <div className={'row'}>
                    <div className={'col s24 m12'}>
                        {/*{() => this.renderCategories()}*/}


                        {this.state.categoriesList && this.state.categoriesList.map(category => {
                            return <Category category={category} key={category.id}/>
                        })}
                    </div>
                </div>
            </div>
        );
    }
}

const mapDisptachToProps = (dispatch) => {
    return {
        getCategories: () => dispatch(getCategories()),
    }
};

const mapStateToProps = (state) => {
    return {
        categories: state.category.categories
    }
};

export default connect(mapStateToProps, mapDisptachToProps)(CategoriesList)

这是 reducer 文件:

 import db from '../firebaseConfig'


const initState = {
    categories: []
};

const categoryReducer = (state=initState, action) => {
    switch (action.type) {
        case 'CREATE_CATEGORY':
            db.collection("Categories").add({
                category: action.category.name
            })
                .then(function(docRef) {
                    db.collection("Categories").get().then((querySnapshot) => {
                        querySnapshot.forEach((doc) => {
                            // console.log(`${doc.id} => ${doc.data().category}`);
                            if(doc.id === docRef.id) {
                                state.categories.push({id: doc.id, name: doc.data().category});
                                console.log(state.categories)
                            }
                        });
                    });
                })
                .catch(function(error) {
                    console.error("Error adding document: ", error);
                });
            break;

        case 'GET_CATEGORIES':
            console.log('Getting data from firestore');

            db.collection("Categories").get().then((querySnapshot) => {
                if(state.categories.length !== querySnapshot.size) {
                    querySnapshot.forEach((doc) => {
                        state.categories.push({id: doc.id, name: doc.data().category});
                    });
                }
            });
            break;
    }
  return state;
};

export default categoryReducer

有没有办法在完全加载数据后更新组件?或者加载 initalState 中所有数据的方法?

最佳答案

有几件事需要理解。第一,this.props.getCategories()执行本质上异步的操作,因此在下一行 this.setState({categoriesList: this.props.categories}); ,我们将得不到所需的数据。

其次,在不进行任何修改的情况下将 props 存储到 state 是没有必要的,并且会导致复杂化。所以尽量直接使用 Prop 而不存储它。如果您要修改获得的 props,请确保覆盖 getDerivedStateFromProps适本地。

第三,尝试使用componentDidMount执行比componentWillMount这样的异步操作。请参阅when to use componentWillMount instead of componentDidMount .

第四(对您的情况很重要),Reducer不应包含异步操作。 Reducer 应该是一个同步操作,它将返回一个新的状态。在您的情况下,您需要在其他地方获取数据,然后 dispatch在您的db.collection(..).then回调。您还可以使用redux-thunk ,如果您使用太多异步操作来更新您的 redux。

因此,如果您遵循在 reducer 中返回新状态的第四点,而不是直接在 db().then 中改变 redux,@Mis94 答案应该有效。 callback

关于node.js - 加载数据后响应更新组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53934693/

相关文章:

javascript - 回复.发送理解吗? (hubot 脚本)

javascript - React Fragment 未在函数中呈现

javascript - react : export function with connected function

ios - 有没有一种方法可以使用 React-Intl 正确格式化,而不会出现此错误?

java - Firebase 更新后 RecyclerView 不刷新

node.js - https GET 请求从浏览器成功但从 Node js 服务器失败

javascript - 创建类与坚持所需模块的单例性质相比,性能是否会受到很大影响?

javascript - Nuxt 抛出 'The "path"argument must be of type string' or console spam

firebase - 如何使用Polymer Fire将数据插入Firebase(多节点+多路径)

firebase - 将子域连接到 firebase