useContext 未在子组件中显示更新的状态(当从全局文件中的 useEffect 挂钩中的 firebase 检索数据时)
Posted
技术标签:
【中文标题】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 【发布时间】:2021-02-17 21:50:47 【问题描述】:我正在使用上下文 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
【问题讨论】:
setProducts(prevProducts);
正在设置本地状态...您在哪里将其存储到您的上下文中?...因为您使用空白 export const ProductsContext = createContext();
创建了上下文并且没有更新上下文...这是为什么当你做const products = useContext(ProductsContext);
时你会空白
如何更新上下文?
***.com/questions/50502664
先生,请检查我的以下答案
【参考方案1】:
只要你的状态是一个对象(或一个数组,但从技术上讲它也是一个对象),你必须避免改变它。
在您的代码中,您通过在原始数组上调用 push(...)
而不是创建它的副本来改变您的 products
数组。
使用变异数组设置状态不会触发更新,因为 React 会将下一个数组的引用与前一个数组的引用进行比较并确定它相等。
要解决这个问题,请创建数组的副本并使用它更新状态:
const prevProducts = [...products];
【讨论】:
先生,这样做,我的 Home.js 中有产品,但我有点陷入尴尬的境地,我不知道如何定义它,但它有点像循环安慰。我现在只有无限数量的产品,而且还在不断增加 请检查我的以下答案【参考方案2】:我不知道如何,但是当我使用相同的方法将我的功能组件 (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>
)
【讨论】:
以上是关于useContext 未在子组件中显示更新的状态(当从全局文件中的 useEffect 挂钩中的 firebase 检索数据时)的主要内容,如果未能解决你的问题,请参考以下文章
反应:无法使用 useContext 钩子在 app.js 中设置上下文状态
如何修改使用 useContext 传递的状态变量(不是 setState 修改,更像是可视化编辑)