簡體   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