当多个状态导致多次重新渲染时,直接在React函数组件中执行代码

时间:2019-05-28 16:26:09

标签: javascript reactjs react-hooks

我有多次使用useState()和其他自定义钩子的组件。

我想根据这些状态值采取行动。我可以直接在功能组件的主体中做到这一点:

const MyComponent = () => {
  const [someState, setSomeState] = useState(false);
  const [otherState, setOtherState] = useState(false);
  const customHookValue = useCustomHook();

  if (someState) foo();
  const foo = () => setOtherState(!otherState);

  if (customHookValue > 10) bar();
  const bar = () => setSomeState(somestate > customHookValue);
}

但是,每次someState发生更改(并且发生重新渲染)时,第二个条件也将运行,如果条件通过,则bar()将运行。感觉不自然。从逻辑上讲,bar()仅在customHookValue更改时才运行,因为someState仅在customHookValue自上次渲染以来已更改时才更改。

总而言之,由someState更改引起的重新渲染不应导致大量不相关的状态设置功能再次运行。即使重新运行它们不会导致程序结果发生变化,但从逻辑上讲这也不对。他们只需要在其相应的条件更改时重新运行即可。它可能会影响性能。

这必须是React中的常见挑战。我对此很陌生,所以我不知道解决这个问题的方法。

问题

  1. 我将如何以建议的方式解决以上问题?
  2. 我是否必须将所有条件包装在useEffectuseMemo中?

编辑:

更新了第二个条件,以使我的问题更清楚(它应取决于customHook)。


澄清:

可能不清楚,我的问题如下。状态更改时,将进行重新渲染。这将导致组件主体中的所有功能重新运行。现在,如果一个组件中有许多useState,并且只有一个更改,那么我在组件主体中定义的一堆可能不相关的状态改变和潜在昂贵的函数将运行。这些状态更改功能仅在它们尝试设置的状态值已更改时才必须运行。如果它们设置的值未更改,则无需再次运行。但是,无论如何,重新渲染都会重新运行组件主体中的所有功能。

1 个答案:

答案 0 :(得分:1)

您似乎想(如其他人所建议的那样)import { Injectable } from '@angular/core'; ^^^^^^ SyntaxError: Unexpected token import at ScriptTransformer._transformAndBuildScript (node_modules/jest- runtime/build/script_transformer.js:403:17)

useEffect

由于您只希望useEffect(() => { if (someState) { setOtherState(!otherState) } }, [someState, otherState]) useEffect(() => { if (customHookValue > 10) { setSomeState(someState > customHookValue) } }, [customHookValue]) 更改时运行setSomeState,因此使其成为传递给customHookValue的依赖项数组中的唯一项。

useEffect eslint-plugin-react-hooks将抱怨第二个useEffect,因为该函数取决于exhaustive-deps的值,即使someState仅在{{1 }} 变化。我也不会担心可能影响性能的事情,除非它们确实会影响性能。我对React的内部知识一无所知,但是它在幕后做了一些事情来避免重新渲染它不需要做的事情,并且可以在绘制实际更新之前进行多次渲染。