我正在使用 React 的上下文 api 来存储收藏夹产品的数组。收藏夹数组填充了布尔值 False 并根据产品的 id 转换为 true。有显示产品卡的收藏页面,带有添加到收藏夹按钮,单击按钮后禁用,但如果产品已存在于收藏夹中,则必须禁用。
现在它在第一页上工作得很好,仅禁用最喜欢的产品,其中包含基于产品索引的 true 和 false 值的数组,但是当导航到另一个页面时,它会禁用同一索引处的其他产品,即使收藏夹数组更新为将所有值设为 false。如果我们返回或移动到另一个页面,其值现在在数组中仍为 false。看起来 UseContext 更新数组的值较晚或在更改时不重新呈现。
我试过实现其他东西,但当数组改变时它仍然不会重新渲染。
这是收藏夹上下文
const FavoritesContext = React.createContext({
addToFavorites: (id,index) => {},
favorites:[],
storedFavorites:(data) => {}
});
export const FavoritesContextProvider = (props) => {
const authCtx = useContext(AuthContext)
const token = authCtx.token;
const userId = authCtx.userId;
const [favorites,setFavorites] = useState([]);
//To retirve Stored Favorites from FireBase
const retriveStoredFavorites = (data) => {
let fav = new Array(data.length).fill(false);
setFavorites(fav);
let queryParams = '?auth=' + token + '&orderBy="userId"&equalTo="' + userId + '"';
axiosInstance.get('/Favorites.json' + queryParams)
.then((response) => {
let fetchProductData = [];
for (let key in response.data) {
fetchProductData.push({
...response.data[key],
productId: key,
});
}
let favoriteList = [];
//To find if the product is present in the Fetched Favorite products List
for(let i=0;i<data.length;i++){
let ids = data[i].id
let favoriteProducts = !!fetchProductData.find((product)=>product.id==ids)
favoriteList.push(favoriteProducts)
}
//console.log(favoriteList)
setFavorites(favoriteList)
});
}
//Add to Favorites
const addTofavoritesHandler = (Product,index) => {
axiosInstance
.post('Favorites.json?auth='+token,Product)
.then((response) => {
//console.log("SUCCESS")
})
.catch((error) => console.log(error));
let favoriteOnes = [...favorites];
favoriteOnes[index] = true;
setFavorites(favoriteOnes);
};
const contextValue = {
addToFavorites:addTofavoritesHandler,
favorites:favorites,
storedFavorites:retriveStoredFavorites
};
return (
<FavoritesContext.Provider value={contextValue}>
{props.children}
</FavoritesContext.Provider>
);
};
export default FavoritesContext;
现在是收藏页面
const CollectionPage = () => {
const classes = useStyles();
const [products, setProducts] = useState([]);
const [filteredProducts, setFilteredProducts] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [productsPerPage] = useState(9);
const [loading, setLoading] = useState(false);
const { enqueueSnackbar } = useSnackbar();
const authCtx = useContext(AuthContext);
const token = authCtx.token;
const userId = authCtx.userId;
const favoriteCtx = useContext(FavoritesContext)
const favorites = favoriteCtx.favorites
//To Display the Products in Main Content
const DisplayProductsHandler = (Data) => {
//Get value of FirstPageNumber and LastPageNumber
const indexOfLastPage = currentPage * productsPerPage;
const indexOfFirstPage = indexOfLastPage - productsPerPage;
//console.log("[Products]")
const productData = Data.slice(indexOfFirstPage, indexOfLastPage);
favoriteCtx.storedFavorites(productData)
//console.log(productData);
const updatedProductData = productData.map((product,index) => {
return (
<ProductCard
Link={`/Info/${product.id}`}
key={product.id}
Title={product.productName}
Image={product.productImage}
Value={product.price}
addToFavorites={() => addTofavoritesHandler(product,index)}
addToCart={() => addToCartHandler(product)}
disableFavoriteButton={favorites[index]}
/>
);
});
setProducts(updatedProductData);
};
//Display the Products from DisplayProductHandler
useEffect(() => {
setLoading(true);
//Scroll To Top When Reloaded
window.scrollTo(0, 0);
//To Display the Products
if (filteredProducts.length === 0) {
DisplayProductsHandler(ProductData);
} else {
DisplayProductsHandler(filteredProducts);
}
setLoading(false);
}, [currentPage, filteredProducts]);
//Add to Favorites Handler
const addTofavoritesHandler =(likedProduct,index) => {
setLoading(true);
let updatedLikedProduct = {
...likedProduct,
userId: userId,
};
favoriteCtx.addToFavorites(updatedLikedProduct,index)
//To Display ADDED TO FAVORITES Message using useSnackbar()
enqueueSnackbar("ADDED TO FAVORITES", { variant: "success" })
setLoading(false);
};
每次更新上下文中的数组时,我都需要它重新渲染。