reactjs 当useEffect和onClick处理程序都调用useCallback函数时,是否有一种方法可以对useEffect进行解释?

qxgroojn  于 2023-11-18  发布在  React
关注(0)|答案(1)|浏览(135)

我有一个类似于这个的伪代码React组件:

const codeApplier = ({ code, prices }: Props) => {
  const [isAccepted, setIsAccepted] = useState(false);

  const applyCode = useCallback(async () => {
    const validationResult = await callToApplyCode(code, prices);

    if (validationResult.status === "OK") {
      setIsAccepted(true);
    } else {
      setIsAccepted(false);
    }
    //do more stuff

  }, [code, prices]);

  useEffect(() => {
    if (isAccepted) applyCode();
  }, [prices]);

  return <button onClick={applyCode} />;
};

字符串
重要的部分:

  • 如果用户单击按钮,我想应用代码
  • 如果价格变化,我想重新应用代码

现在,这样的组件可以正常工作,但是linter会抱怨在useEffect上我没有列出所有的依赖项。
问题是:如果我像这样将“applyCode”(甚至isAccepted)添加到useEffect的依赖项中:

useEffect(() => {
    if (isAccepted) applyCode();
  }, [isAccepted, applyCode, prices]);


然后linter会很高兴,但是useEffect会在每次点击时复制调用。
1.更改“代码”->自动更改“applycode”->预期

  1. onclick -> call the new applycode -> Expected
  2. callToApplyCode ->预期
    1.“applycode”更改触发的useEffect-> applycode(); ->意外
    1.另一个callToApplyCode ->不需要
    在这种情况下,禁用exhaustive-deps是可以的吗?或者有没有一种方法可以在不激怒linter的情况下重构组件?
    我看了这个评论:https://github.com/facebook/react/issues/14920#issuecomment-471070149和StackOverflow上的各种类似问题,但我无法找到我的具体案例的答案。
zd287kbt

zd287kbt1#

如果你只想让prices的变化触发useEffect,保存prices的前一个状态到一个ref中,并且每当useEffect被deps变化触发时,检查当前和前一个价格是否相同。如果相同,退出。

const codeApplier = ({ code, prices }: Props) => {
  const prevPricesRef = useRef(prices); // ref for previous state of prices
  const [isAccepted, setIsAccepted] = useState(false);

  const applyCode = useCallback(async() => {
    const validationResult = await callToApplyCode(code, prices);

    setIsAccepted(validationResult.status === "OK");

    //do more stuff

  }, [code, prices]);

  useEffect(() => {
    if(prices === prevPricesRef.current) return; // bail out if current & prev prices are identical
    
    prevPricesRef.current = prices; // update prev prices
  
    if (isAccepted) applyCode();
  }, [prices, isAccepted, applyCode]);

  return <button onClick={applyCode} />;
};

字符串

相关问题