当组件值更新时,UseContext 不会重新渲染

时间:2021-07-19 10:14:51

标签: javascript arrays reactjs use-state use-context

我正在使用 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);
  };

每次更新上下文中的数组时,我都需要它重新渲染。

0 个答案:

没有答案