【问题标题】:How to execute useEffect hook callback only when a single value from the hook callback changes?仅当挂钩回调中的单个值更改时,如何执行 useEffect 挂钩回调?
【发布时间】:2022-01-26 22:01:37
【问题描述】:

react documentation 中提到,每个应该更改的东西都需要存在于 useEffect 挂钩的依赖数组中。

我可以使用// eslint-disable-next-line react-hooks/exhaustive-deps,但我认为这不是理想的方式。

但是,如果您只想在某个状态发生变化时触发副作用,您会怎么做?其他东西不习惯吗?

我有一个解决方法,但如果您在监听独特状态时有多个副作用,则该方法不起作用。

const [state1, setState1] = useState(1);
const [state2, setState2] = useState(2);

const fetchDataWithState = useCallback(() => {
  action.fetchData({
    state1,
    state2,
  })
}, [state1, state2])

// Effect to listen to the changes of state1
useEffect(() => {
  // Some random work related to state1
  fetchDataWithState()
}), [fetchDataWithState, state1])

// Effect to listen to the changes of state2
useEffect(() => {
  // Some random work related to state2
  fetchDataWithState()
}), [fetchDataWithState, state2])

如果有多个副作用,则上面的代码不起作用,每个副作用都特定于特定的状态。

如果state1 发生更改,fetchDataWithState 将具有不同的引用,因此它将导致在第二个useEffect 中执行回调,该回调应该仅在state2 更改时触发。

或者我应该通过不在依赖数组中传递fetchDataWithState 来使用// eslint-disable-next-line react-hooks/exhaustive-deps

【问题讨论】:

  • 你当前的代码相当于useEffect(() => { fetchDataWithState(); fetchDataWithState(); }, [fetchDataWithState]);是的,你应该听警告。
  • @PatrickRoberts 重新表述了这个问题。仅当其中的单个状态发生更改时,如何执行useEffect 回调? useEffect(() => { action.fetchData({ state1, state2 }) }, [state1])

标签: reactjs react-hooks use-effect use-state usecallback


【解决方案1】:

state1 的先前值存储在ref 中,并且仅在state1 实际更改时才调用该函数:

const [state1, setState1] = useState(1);
const [state2, setState2] = useState(2);
const state1PreviousRef = useRef(0); // Any initial value that's the same type as state1, but not the same value

// only invoke action.fetchData if state1 changes:
useEffect(() => {
  // state1 changed from last time
  if (state1 !== state1PreviousRef.current) {
    action.fetchData({state1, state2});
  }

  // update previous to current
  state1PreviousRef.current = state1;
}, [
  state1,
  state2,
  action, // might or might not be necessary, depending on where this is defined (you don't show this in your example)
  state1PreviousRef, // not necessary, but **actually** exhaustive
]);

【讨论】:

  • @PatrickRoberts 好电话。这不是我在编辑器中写的:谢谢你看到这个。
  • 这可行,但我认为这不是理想的方式,因为可能有“N”个状态,我必须为每个状态设置一个单独的参考?还有支票。
  • (1/2) 如果他们需要一起行动,那么他们为什么要分开状态?
  • (2/2) 没有什么能阻止您将 n 项存储在单个 ref 中的数组或对象中并使用该单个集合。
  • 不,除非你错过了this
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多