我有一个伪代码Reaction组件,与下面的组件类似:

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} />;
};

重要部分:

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

现在,像这样的组件工作得很好,但Lintert抱怨说,在useEffect上,我没有列出所有的依赖项.臭名昭著的穷举法.

问题是:如果我像这样将"applyCode"(甚至isAccepted)添加到useEffect的依赖项中:

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

然后,林特很高兴,但useEffect将在每次点击时重复调用.

  1. 更改"code"-&gt;自动更改"applycode"-预期为&gt;
  2. OnClick-&>调用新的应用程序代码-&>预期
  3. CallToApplyCode-应为&gt;
  4. "applycode"更改触发的useEffect-&gt;applycode();-&gt;意外
  5. 另一个调用ToApplyCode-&gt;不需要

这是不是属于这样一种情况:禁用穷举alert 是可以的? 或者,有没有一种方法可以在不惹恼林特的情况下重构组件?

我看了这条 comments :https://github.com/facebook/react/issues/14920#issuecomment-471070149 以及StackOverflow上的各种类似问题,但我无法找到我具体 case 的答案.

推荐答案

如果只希望prices的变化触发useEffect,请将先前的prices状态保存在REF中,并且每当DPS变化触发useEffect时,判断当前和之前的价格是否相同.如果他们是,那就跳出困境.

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} />;
};

Reactjs相关问答推荐

无法覆盖MUI工具栏上的左右填充,除非使用!重要

在带有和设计的表格中禁用和取消选中复选框

react 路由导航不工作,但手动路由工作

使用Reaction钩子窗体验证可选字段

StyleX中的多语言支持

shadcn输入+窗体+Zod;一个部件正在改变要被控制的不受控制的输入;

Github 操作失败:发布 NPM 包

Javascript - 正则表达式不适用于 MAC OS - 编码?

React Wordpress Apache 在索引之外重新加载 -> 未找到页面

在Vite React上获取Amplify的环境变量

如何在 React Native 中更新跨屏幕呈现的上下文状态变量?

动态添加或删除文本输入字段并将值设置为 React JS 中主要状态的数组

为什么接受 useState 返回的函数的 setter 在使用 React 的单个调用中执行两次?

当用户输入相同信息时如何禁用更新

错误:无效挂钩调用.钩子只能在函数组件的主体内部调用.使用 next/router 时

调用 Jest 和服务方法的问题

Cypress - 在继续之前等待下一个按钮重新出现

加密 Django Rest Framework API 响应 + 解密响应应用程序中的响应

在 React 中,为什么不能向空片段添加键(短语法)?

从输入中获取数字时,react 计数器不会增加