【问题标题】:is it alright to have a ref on state (from a reducer) to avoid creating new callbacks?可以对状态(来自reducer)进行引用以避免创建新的回调吗?
【发布时间】:2022-01-11 00:46:48
【问题描述】:

我经常有这样一个用例,reducer 中有一些状态,也需要在一些回调(useCallback)中访问它

const [state, dispatch] = useReducer(reducer, initialState);
...
const handleAction = useCallback(()=>{
   // dependency on state 
},[])

为了避免在每次状态更改时运行 useCallbacks,我会联系一个 ref 并在每次渲染时为其分配状态

 stateRef.current = state;

然后,无论何时我必须在回调中使用 state 中的某些内容,都可以从 stateRef 访问它。这是正确的做法吗?

【问题讨论】:

  • 当然。你在寻找什么样的答案?使用依赖于状态的useEffect 和使用依赖于状态的useCallback 之间没有太大区别吗?您正在谈论使用useEffect 挂钩来正确更新stateRef 值,对吧?

标签: javascript reactjs react-hooks


【解决方案1】:

如果您只是从组件主体更新stateRef,那么这不是最正确的方法,因为这会被认为是无意的副作用。如果不使用依赖于 stateuseCallback 挂钩将当前状态值重新包含在回调函数中,则建议使用依赖于状态值的 useEffect

const [state, dispatch] = useReducer(reducer, initialState);
const stateRef = useRef();

useEffect(() => {
  stateRef.current = state;
}, [state]);

const handleAction = ()=>{
  // access stateRef.current
};

这实际上是 useCallback 完成的工作,但方式更简洁。

const [state, dispatch] = useReducer(reducer, initialState);

const handleAction useCallback(() => {
  // access current state value closed over in scope
}, [state]);

【讨论】:

  • 感谢 Drew,我同意将状态作为 handleAction 回调的依赖项是正确的做法,根据状态的不同部分使用多个回调,它会创建这些函数的新实例并进一步触发重新渲染组件。如何以一种好的方式避免这些重新渲染可能是一个有趣的发现。
  • @RahilAhmad 是否有任何重新渲染有问题或导致任何性能问题? React 已经过优化并且开箱即用运行良好,目标是 60fps,或者如果您正在执行一些繁重的状态更新/重新渲染触发器,则每个渲染周期大约 17 毫秒。
猜你喜欢
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 2010-11-06
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多