渲染不同的组件时无法更新组件 - ReactJS

时间:2021-07-13 10:35:00

标签: reactjs react-context

我知道很多开发者过去都遇到过类似的问题。我经历了其中的大部分,但无法解决问题。

我正在尝试更新购物车上下文计数器值。以下是代码(store/userCartContext.js 文件)

import React, { createContext, useState } from "react";

const UserCartContext = createContext({
  userCartCTX: [],
  userCartAddCTX: () => {},
  userCartLength: 0
});

export function UserCartContextProvider(props) {
  const [userCartStore, setUserCartStore] = useState([]);

  const addCartProduct = (value) => {
    setUserCartStore((prevState) => {
      return [...prevState, value];
    });
  };

  const userCartCounterUpdate = (id, value) => {
    console.log("hello dolly");
    // setTimeout(() => {
    setUserCartStore((prevState) => {
      return prevState.map((item) => {
        if (item.id === id) {
          return { ...item, productCount: value };
        }
        return item;
      });
    });
    // }, 50);
  };

  const context = {
    userCartCTX: userCartStore,
    userCartAddCTX: addCartProduct,
    userCartLength: userCartStore.length,
    userCartCounterUpdateCTX: userCartCounterUpdate
  };

  return (
    <UserCartContext.Provider value={context}>
      {props.children}
    </UserCartContext.Provider>
  );
}

export default UserCartContext;


这里我已经注释掉了 setTimeout 函数。如果我使用 setTimeout,它可以完美运行。但我不确定这是否是正确的方法。

cartItemEach.js 文件中,我使用以下代码更新上下文

const counterChangeHandler = (value) => {
    let counterVal = value;
    userCartBlockCTX.userCartCounterUpdateCTX(props.details.id, counterVal);
};

CodeSandBox 链接:https://codesandbox.io/s/react-learnable-one-1z5td

当我更新 CART 弹出窗口内的计数器时会出现问题。如果您只更新计数器一次,则不会有任何错误。但是当您多次更改计数器时,控制台内会弹出此错误。即使出现此错误,也不会影响整个代码。更新后的计数器值存储在 Context 的状态中。

1 个答案:

答案 0 :(得分:0)

提示您不能从传递给另一个 setState 函数的函数中调用 setState 函数。在传递给 setState 函数的函数中,您应该只专注于更改该状态。您可以使用 useEffect 使该状态更改触发另一个状态更改。

以下是重写 Counter 类以避免收到警告的一种方法:

  const decrementHandler = () => {
    setNumber((prevState) => {
      if (prevState === 0) {
        return 0;
      }
      return prevState - 1;
    });
  };

  const incrementHandler = () => {
    setNumber((prevState) => {
      return prevState + 1;
    });
  };

  useEffect(() => {
    props.onCounterChange(props.currentCounterVal);
  }, [props.currentCounterVal]);
  // or [props.onCounterChange, props.currentCounterVal] if onCounterChange can change

我不清楚 useEffect 是否需要在 Counter 类中;鉴于当前值和回调均由父级提供,您可能会将 useEffect 移到父级之外。但这取决于您以及您想要实现的目标。