从 useState 设置状态而不触发 useEffect 钩子

时间:2021-03-01 08:08:47

标签: javascript reactjs

问题

我想防止触发在依赖数组中包含 useState 值的 useEffect 钩子。为了清楚起见,请看示例。

详细说明

在初始化过程中,表单会设置一些值,因此我定义了一个标志,以防止其他效果在完全初始化之前执行,但我也不想在初始化标志状态更改时触发第二个效果.

我能否以某种方式阻止跟踪此 User.findByIdAndUpdate( { _id: p[0].user }, { $pull: { likes: p[0]._id } } ) .then((user) => { console.log("User updated "); }) 状态? 我找不到解决我问题的线程。您能否将与此相关的线程联系起来?提前致谢。

示例

isInitialization

3 个答案:

答案 0 :(得分:2)

尝试从依赖数组中删除 isInitialization

  useEffect(() => {
    if (isInitialization) {
      form.setFieldsValue({
        ...settings,
      });
      setIsInitialization(false); // <-- This should not trigger any useEffect
    }
  }, [settings, form]);

As React docs says:

<块引用>

如果你想运行一个效果并且只清理它一次(在安装和 unmount),您可以传递一个空数组 ([]) 作为第二个参数。这 告诉 React 你的效果不依赖于来自 props 的任何值 或状态,所以它永远不需要重新运行。这不作为特殊处理 case — 它直接遵循依赖项数组始终的方式 有效。

更新:

Building Your Own Hooks

<块引用>

构建您自己的 Hooks 可以让您将组件逻辑提取为可重用的 功能。

如果是通用逻辑,那么您可以创建自定义钩子并跨组件共享。

«useMyCustomHook.jsx» 文件:

import { useEffect } from 'react';

export default function useMyCustomHook(str) {
  useEffect(() => {
      console.log(`title`, title);
  });
}

然后在组件中使用:

function fooFunction(props) {
  const [firstName, setFirstName] = useState('');

  useMyCustomHook(`This is ${firstName}`);

  return (        
      <div>The firstname is {firstName}</div>
  );
}

答案 1 :(得分:1)

特别感谢@Martin。这个解决方案实际上并没有解决跳过 useEffect 触发的问题,而是帮助我进一步重构了我的代码。也许这不相关,但我还是想和你分享我的结果:

最后看起来像这样。不再需要初始化标志,因为自定义钩子已经做了:

const useAntForm = (initalData) => {
  const [form] = useForm();
  form.setFieldsValue({
    ...initalData,
  });

  return form;
};

export function SomeComponent({
  settingsChanges,
  initialSettings,
}: SettingsProps) {
  const form = useAntForm(initialSettings);
  const [settings, setSettings] = useState(initialSettings);
  const [isValid, setIsValid] = useState(false);
  .
  .
  .
}

答案 2 :(得分:0)

根据 https://reactjs.org/docs/hooks-rules.html,可以在 useEffect 钩子中忽略不应触发重新渲染的依赖项。通常在省略依赖项时它会说

<块引用>

React Hook useEffect 缺少依赖项:'someDependency'。包括它或删除依赖项数组。

为了解决这个问题,您只需将 https://www.npmjs.com/package/eslint-plugin-react-hooks 添加到您的 eslint 配置中,该配置主要位于 package.json 文件中

我的配置现在看起来像:

package.json

{
 ...
 "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "plugins": [
      "react-hooks"  // <-- Added this
    ]
  },
  ...
}