英文:
Prevent <canvas> re-render on state change?
问题
I am using hooks, with React 16.9.
我正在使用 hooks,与 React 16.9。
I have a component that renders an HTML canvas element. The issue is that I have event handlers that change component state, which in turn re-renders my canvas element and erases the drawing I've done. If I were using class components, I may be able to add shouldComponentUpdate() {return false;}
, but I am not sure of the equivalent for hooks.
我有一个渲染 HTML 画布元素的组件。问题是,我有改变组件状态的事件处理程序,这反过来重新渲染了我的画布元素并擦除了我所做的绘图。如果我使用类组件,我可能可以添加 shouldComponentUpdate() {return false;}
,但我不确定 hooks 的等效方式。
const Canvas = () => {
const [hover, setHover] = useState(false);
const myRef = useRef();
useEffect(() => {
// perform a one-time drawing on the canvas element that should be retained throughout state changes
myRef.current.addEventListener('mouseover', () => setHover(true));
myRef.current.addEventListener('mouseout', () => setHover(false));
}, [])
return (
{hover && <p>Hovering</p>}
<canvas ref={myRef}>
);
}
英文:
I am using hooks, with React 16.9.
I have a component that renders an HTML canvas element. The issue is that I have event handlers that change component state, which in turn re-renders my canvas element and erases the drawing I've done. If I were using class components, I may be able to add shouldComponentUpdate() {return false;}
, but I am not sure of the equivalent for hooks.
const Canvas = () => {
const [hover, setHover] = useState(false);
const myRef = useRef();
useEffect(() => {
// perform a one-time drawing on the canvas element that should be retained throughout state changes
myRef.current.addEventListener('onmouseover', () => setHover(true));
myRef.current.addEventListener('onmouseout', () => setHover(false));
}, [])
return (
{hover && <p>Hovering</p>}
<canvas ref = {myRef}>
);
}
答案1
得分: 1
你对状态概念的理解不准确,在99.99%的情况下,它用于保持组件更新。如果不需要更新组件,可以使用ref。
另外,你可以将画布放入一个单独的组件中,并为悬停事件添加回调函数。不要忘记在画布的子组件中使用memo函数包装,以防止重新渲染。
英文:
You have an inaccurate understanding of the concept of state, in 99.99% of cases it is used to keep the component updated. If you do not need to update the component, you can use ref.
Also you can put the canvas into a separate component and add callbacks to events of hover. Don't forget to wrap child component of canvas in memo function, that prevent to re-render.
答案2
得分: 1
这个React函数组件似乎需要像React.PureComponent一样工作,尝试将整个React函数组件包裹在react.memo(function)中。
const Canvas = React.memo(() => {
const [hover, setHover] = useState(false);
const myRef = useRef();
useEffect(() => {
// 在canvas元素上执行一次性绘制,应在状态更改期间保留
myRef.current.addEventListener('mouseover', () => setHover(true));
myRef.current.addEventListener('mouseout', () => setHover(false));
}, [])
return (
{hover && <p>悬停</p>}
<canvas ref={myRef}></canvas>
);
})
英文:
Sounds like this react functional component needs to behave like a React.PureComponent try wrapping your entire react functional component in a react.memo(function).
const Canvas = React.memo(() => {
const [hover, setHover] = useState(false);
const myRef = useRef();
useEffect(() => {
// perform a one-time drawing on the canvas element that should be retained throughout state changes
myRef.current.addEventListener('onmouseover', () => setHover(true));
myRef.current.addEventListener('onmouseout', () => setHover(false));
}, [])
return (
{hover && <p>Hovering</p>}
<canvas ref = {myRef}>
);
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论