我正在使用上下文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
答案 0 :(得分:0)
无论何时状态是一个对象(或数组,但从技术上讲也是一个对象),都必须避免对其进行突变。
在您的代码中,您正在对products
数组进行突变,方法是在原始数组上调用push(...)
而不是为其创建副本。
使用变异数组设置状态不会触发更新,因为React将下一个数组的引用与前一个数组的引用进行比较,并确定其相等。
要解决此问题,请创建该数组的副本并使用该状态更新状态:
const prevProducts = [...products];
答案 1 :(得分:0)
我不知道如何,但是当我使用相同的方法将功能组件(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>
)
}
}