阻止<canvas>在状态更改时重新渲染?

huangapple go评论71阅读模式
英文:

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 = () =&gt; {

const [hover, setHover] = useState(false);
const myRef = useRef();

useEffect(() =&gt; {

  // perform a one-time drawing on the canvas element that should be retained throughout state changes

  myRef.current.addEventListener(&#39;onmouseover&#39;, () =&gt; setHover(true));
  myRef.current.addEventListener(&#39;onmouseout&#39;, () =&gt; setHover(false));

}, [])

return (
  {hover &amp;&amp; &lt;p&gt;Hovering&lt;/p&gt;}
  &lt;canvas ref = {myRef}&gt;
);

}

答案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(() =&gt; {

const [hover, setHover] = useState(false);
const myRef = useRef();

useEffect(() =&gt; {

  // perform a one-time drawing on the canvas element that should be retained throughout state changes

  myRef.current.addEventListener(&#39;onmouseover&#39;, () =&gt; setHover(true));
  myRef.current.addEventListener(&#39;onmouseout&#39;, () =&gt; setHover(false));

}, [])

return (
  {hover &amp;&amp; &lt;p&gt;Hovering&lt;/p&gt;}
  &lt;canvas ref = {myRef}&gt;
);

}) 

huangapple
  • 本文由 发表于 2020年1月6日 21:33:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/59613060.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定