我有多次使用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中的常见挑战。我对此很陌生,所以我不知道解决这个问题的方法。
问题
useEffect
或useMemo
中?编辑:
更新了第二个条件,以使我的问题更清楚(它应取决于customHook)。
澄清:
可能不清楚,我的问题如下。状态更改时,将进行重新渲染。这将导致组件主体中的所有功能重新运行。现在,如果一个组件中有许多useState
,并且只有一个更改,那么我在组件主体中定义的一堆可能不相关的状态改变和潜在昂贵的函数将运行。这些状态更改功能仅在它们尝试设置的状态值已更改时才必须运行。如果它们设置的值未更改,则无需再次运行。但是,无论如何,重新渲染都会重新运行组件主体中的所有功能。
答案 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的内部知识一无所知,但是它在幕后做了一些事情来避免重新渲染它不需要做的事情,并且可以在绘制实际更新之前进行多次渲染。