繁体   English   中英

useContext 未在子组件中显示更新的状态(当从全局文件中 useEffect 钩子中的 firebase 检索数据时)

[英]useContext is not displaying the updated state (when data is retrieved from firebase in useEffect hook in global file) in child component

我正在使用上下文 api 来获得产品的全局状态,为此我有 ProductsContext.js

我在 ProductsContext.js 中有一个像这样定义的空数组状态

const [products, setProducts] = useState([]);

在同一个文件 (ProductsContext.js) 中,我使用 useEffect 从 firebase 检索所有产品,然后更新产品状态。 以下是 ProductsContext.js 的所有代码

import React, { createContext, useState, useEffect } from 'react'
import { db } from '../Config/Config'

export const ProductsContext = createContext();

export const ProductsContextProvider = (props) => {
    // console.log(props);
    const [products, setProducts] = useState([]);

    useEffect(() => {
        // console.log('use effect');
        const prevProducts = products;
        db.collection('Products').onSnapshot(snapshot => {
            let changes = snapshot.docChanges();
            changes.forEach(change => {
                if (change.type === 'added') {
                    prevProducts.push({
                        ProductID: change.doc.id,
                        ProductName: change.doc.data().ProductName,
                        ProductDescription: change.doc.data().ProductDescription,
                        ProductPrice: change.doc.data().ProductPrice,
                        ProductImg: change.doc.data().ProductImg
                    })
                }
                // console.log(prevProducts);
                setProducts(prevProducts);
                console.log(products); // I am able to see the products in console
            })
        })
    })

    return (
        <ProductsContext.Provider value={{ products: [...products] }}>
            {props.children}
        </ProductsContext.Provider>
    )
}

我的问题是 Home.js 是我的子组件,我在这个文件中使用 useContext 但它没有返回更新的状态而只返回一个空数组

import React, { useContext } from 'react'
import { ProductsContext } from '../Global/ProductsContext'

export const Home = () => {
    const { products } = useContext(ProductsContext);
    console.log(products); // empty array
    return (
        <div>

        </div>
    )
}

这是我的 app.js

import React, { Component } from 'react'
import { ProductsContextProvider } from './Global/ProductsContext'
import { Home } from './Components/Home'

export class App extends Component {
    render() {
        return (
            <ProductsContextProvider>
                <Home />
            </ProductsContextProvider>
        )
    }
}

export default App

每当您的状态是一个对象(或一个数组,但从技术上讲也是一个对象)时,您必须避免对其进行变异。

在您的代码中,您通过在原始数组上调用push(...)而不是创建它的副本来改变您的products数组。

使用变异数组设置状态不会触发更新,因为 React 会将下一个数组的引用与前一个数组的引用进行比较并确定它们相等。

要解决此问题,请创建数组的副本并使用以下内容更新状态:

const prevProducts = [...products];

我不知道如何但是当我使用相同的方法将我的功能组件 (ProductsContext.js) 更改为基于类的组件时,它以某种方式工作并且我能够在我的子组件中获取产品。 这是代码

import React, { createContext } from 'react'
import { db } from '../Config/Config'

export const ProductsContext = createContext();

export class ProductsContextProvider extends React.Component {

    state = {
        products: []
    }

    componentDidMount() {

        const prevProducts = this.state.products;
        db.collection('Products').onSnapshot(snapshot => {
            let changes = snapshot.docChanges();
            changes.forEach(change => {
                if (change.type === 'added') {
                    prevProducts.push({
                        ProductID: change.doc.id,
                        ProductName: change.doc.data().ProductName,
                        ProductDescription: change.doc.data().ProductDescription,
                        ProductPrice: change.doc.data().ProductPrice,
                        ProductImg: change.doc.data().ProductImg
                    })
                }
                // console.log(prevProducts);
                this.setState({
                    products: prevProducts
                })
                // console.log(this.state.products);
            })
        })

    }
    render() {
        return (
            <ProductsContext.Provider value={{ products: [...this.state.products] }}>
                {this.props.children}
            </ProductsContext.Provider>
        )
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM