您将如何从头开始使用useState来实现useCallback?

时间:2020-09-26 15:25:36

标签: reactjs react-hooks

这就是我实现它的方式。这样看起来还好吗?

function useCallback(fn, deps) {
    const [state, setState] = useState({ fn });

    useEffect(() => {
        setState({ fn });
    }, deps);

    return state.fn;
}

1 个答案:

答案 0 :(得分:1)

不错的尝试,但并不完美。您的实现调用setState()会触发另一轮组件的重新渲染,这与真实的useCallback()挂钩的行为不符。

接受确定的挑战。

实际上,useState()并不是实施useCallback()的良好基础,useRef()更好。但是为了满足您的要求,lemme首先用useRef()useState()

function useRef(value) {
  const [ref] = useState({ current: value })
  ref.current = value
  return ref
}

轻松虔诚。我们不需要useEffect()。我们只需要一个函数来比较重新渲染之间的深度,看看它们是否改变。

function depsChanged(deps1, deps2) {
  if (deps1 === undefined || deps2 === undefined) return true
  if (deps1.length !== deps2.length) return true
  for (let i in deps1) {
    if (!Object.is(deps1[i], deps2[i])) return true
  }
  return false
}

现在我们可以实现useCallback()

function useCallback(fn, deps) {
  const slots = useRef([fn, deps]).current
  if (depsChanged(slots[1], deps)) {
    slots[0] = fn
  }
  slots[1] = deps
  return slots[0]
}