如何解决如何在道具更改时更新状态,而无需渲染两次
我有一个数据可视化组件,它的属性之一是“宽度”。状态跟踪图表中的缩放级别,并在处理鼠标事件时更新。
当宽度改变时需要调整缩放。目前,我正在 useEffect 钩子中执行此操作:
function MyComponent({width}) {
const [zoom,setZoom] = useState(...)
useEffect(() => {
setZoom(adjustZoom(zoom,width))
},[width])
const handleMouseEvent = (event) => {
setZoom(calculateNewZoom(event))
}
...
}
但这会使组件渲染两次:一次用于宽度更新,一次用于缩放更新。由于第一个渲染在屏幕上闪烁,因此并不理想。
理想情况下,组件只渲染一次,同时反映宽度和缩放的变化。如何用钩子实现这一点?另外,这个概念有名字吗?提前致谢。
解决方法
由于第一个渲染在屏幕上闪烁,所以并不理想。
这就是 useLayoutEffect()
旨在解决的问题,作为 useEffect()
的直接替代品。
不过,您还有另一个潜在问题,那就是您的 useEffect()
包含 stale reference 到 zoom
。为了获得正确的引用,请改用 setZoom()
的 functional update 形式:
function MyComponent({ width }) {
const [zoom,setZoom] = useState(...)
useLayoutEffect(() => {
setZoom((zoom) => adjustZoom(zoom,width))
},[width])
const handleMouseEvent = (event) => {
setZoom(calculateNewZoom(event))
}
...
}
或者,您可以考虑删除 useLayoutEffect()
和 using a memoized adjustedZoom
以避免双重渲染:
function MyComponent({ width }) {
const [zoom,setZoom] = useState(...)
const adjustedZoom = useMemo(() => {
return adjustZoom(zoom,width)
},[zoom,width])
const handleMouseEvent = (event) => {
setZoom(calculateNewZoom(event))
}
...
// now use adjustedZoom where you would have used zoom before
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。