ChenPt / dailyNote

dailyNode for myself
https://github.com/ChenPt/dailyNote/issues
0 stars 0 forks source link

useEvent #47

Open ChenPt opened 2 years ago

ChenPt commented 2 years ago

有如下的Demo

function Demo() {
  const [text, setText] = useState('')

  const onClick = () => {
    sendMessage(text)
  }

  return <Button onClick={onClick} />
}

假设Button是个高开销的组件,要对其进行性能优化处理,优化props.onClick,使用useCallback包裹,使得onClick引用保持不变,但是这样onClick就无法获取到最新的text,通常我们的hack做法是,定义一个textRef,存储最新的text,在onClick里使用textRef获取最新的text。

function Demo() {
  const [text, setText] = useState('')
  const textRef = useRef(text)
  useEffect(() => { textRef.current = text }, [text])

  const onClick = useCallback(() => {
    sendMessage(textRef.current)
  }, [])

  return <Button onClick={onClick} />
}

现在React有个提案就是解决这个问题。useEvent

https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md

function Demo() {
  const [text, setText] = useState('')

  // onClick引用保持不变,且能获取到最新的text
  const onClick = useEvent(() => {
    sendMessage(text)
  })

  return <Button onClick={onClick} />
}
function useEvent(handler) {
  const handlerRef = useRef(handler)

  useLayoutEffect(() => {
    handlerRef.current = handler
  })
  return useCallback((...args) => {
    const fn = handlerRef.current;
    return fn(...args)
  }, [])
}