title: context.putImageData() Not working in React
body: <p>Im trying to create a drawing application in react, its working for the most part. But when i try add an undo button it doesnt work.</p>
  <p>I try make the undo button with this <code>finishDrawing()</code> function, where i use getImageData and store it in an array called <code>restore_array</code></p>
  <pre><code>    const finishDrawing = () =&gt; {
          //console.log(contextRef.current)
          contextRef.current.closePath()
          setIsDrawing(false)
          //restore_array.push(contextRef.current.getImageData(0, 0,400,256+80))
          setIndex_array(index_array + 1)
          setRestore_Array((prevState) =&gt; { return [...prevState, contextRef.current.getImageData(0, 0,400,256+80)]})
          console.log(restore_array, restore_array.length)
          
      }
  </code></pre>
  <p>then when a Undo button is clicked i try to reload this image in the <code>restore_array</code> with a <code>useEffect</code> which should re-render the entree canvas with the previous image</p>
  <pre><code>    function undoLast() {
          console.log(restore_array[index_array], index_array, restore_array)
          if (index_array &gt; -1) {
              setIndex_array(index_array-1)
              restore_array.pop()
              setLines(!lines)
  
          }
          //contextRef.current.putImageData(restore_array[index_array-1], 0, 0)   
      }
  </code></pre>
  <p>and</p>
  <pre><code>    useEffect(() =&gt; {
          console.log('use effect 3c')
          console.log(restore_array)
          const canvas = canvasRef.current;
          const context = canvas.getContext(&quot;2d&quot;)
          context.lineWidth = thick
          context.lineCap = &quot;round&quot;
          context.strokeStyle = colour
          if (restore_array.length === 0) {
              console.log('empty')
              return
          }
          //context.clearRect(0,0,400,256+80)
          //context.fillRect(0,0,400,256+80)
          context.putImageData(restore_array[index_array], 0, 0, 0, 0, 400, 256+80)
          contextRef.current = context
      }, [lines])
  
  </code></pre>
  <p>Does anyone know why my <code>putImageData</code> isnt working in this case?</p>
  <p>Heres my entire code for reference</p>
  <pre><code>import React, { useEffect, useRef, useState } from &quot;react&quot;;
  
  
  
  function DrawCanvas() {
  
      const canvasRef = useRef(null)
      const contextRef = useRef(null)
      const [isDrawing, setIsDrawing] = useState(false)
      const [colour, setColour] = useState('black')
      const [prcolour, setPrColour] = useState(null)
      const [thick, setThick] = useState(3)
      const [image, setImage] = useState(null)
      const [restore_array, setRestore_Array] = useState([])
      const [index_array, setIndex_array] = useState(-1)
      const [clear_, setClear_] = useState(true)
      const [lines, setLines] = useState(true)
      //let restore_array = []
  
  
  
  
  
      useEffect(() =&gt; {
          const canvas = canvasRef.current;
          canvas.width = window.innerWidth/1.5 ;
          canvas.height = window.innerHeight/1.5 ;
          canvas.style.width = `${window.innerWidth/3}px`;
          canvas.style.height = `${window.innerHeight/3}px`;
          const context = canvas.getContext(&quot;2d&quot;)
          context.scale(2,2)
          context.lineCap = &quot;round&quot;
          context.lineWidth = 3
          context.strokeStyle = &quot;black&quot;
          //const img = DogImage
          context.fillStyle = 'gray'
          context.fillRect(0,0,400,256+80)
          contextRef.current = context
          
      }, [])
  
  
  
  
      useEffect(() =&gt; {
          console.log('use effect 1a')
          const canvas = canvasRef.current;
          const context = canvas.getContext(&quot;2d&quot;)
          context.lineWidth = thick
          context.lineCap = &quot;round&quot;
          context.strokeStyle = colour
          contextRef.current = context
          document.getElementById(colour).style.borderColor = 'gray'
          if(prcolour === null) {
              return
          }
          document.getElementById(prcolour).style.borderColor = 'black'
          document.getElementById(prcolour).style.borderWidth = '3px'
  
      }, [colour])
  
      useEffect(() =&gt; {
          console.log('use effect 2b')
          const canvas = canvasRef.current;
          const context = canvas.getContext(&quot;2d&quot;)
          context.lineWidth = thick
          context.lineCap = &quot;round&quot;
          context.strokeStyle = colour
          const Dogimage = new Image();
          Dogimage.src = '../../images/dog-without-labels.png'
          Dogimage.onLoad = () =&gt; {
              console.log('load image')
              context.current.drawImage(Dogimage, 0, 0,400,256+80);
          }
          contextRef.current = context
      }, [thick])
  
      useEffect(() =&gt; {
          console.log('use effect 3c')
          console.log(restore_array)
          const canvas = canvasRef.current;
          const context = canvas.getContext(&quot;2d&quot;)
          context.lineWidth = thick
          context.lineCap = &quot;round&quot;
          context.strokeStyle = colour
          if (restore_array.length === 0) {
              console.log('empty')
              return
          }
          //context.clearRect(0,0,400,256+80)
          //context.fillRect(0,0,400,256+80)
          context.putImageData(restore_array[index_array], 0, 0, 0, 0, 400, 256+80)
          contextRef.current = context
      }, [lines])
  
      useEffect(() =&gt; {
          console.log('use effect 4d')
          const canvas = canvasRef.current;
          const context = canvas.getContext(&quot;2d&quot;)
          //contextRef.fillStyle = 'gray'
          context.lineWidth = thick
          context.lineCap = &quot;round&quot;
          context.strokeStyle = colour
          context.clearRect(0,0,400,256+80)
          context.fillRect(0,0,400,256+80)
          contextRef.current = context
      }, [clear_])
  
      
  
  
      function undoLast() {
          console.log(restore_array[index_array], index_array, restore_array)
          if (index_array &gt; -1) {
              setIndex_array(index_array-1)
              restore_array.pop()
              setLines(!lines)
  
          }
          //contextRef.current.putImageData(restore_array[index_array-1], 0, 0)   
      }
  
      const clearCanvas = () =&gt; {
          setClear_(!clear_)
      }
  
  
  
      const startDrawing = ({nativeEvent}) =&gt; {
          const {offsetX, offsetY} = nativeEvent
          contextRef.current.beginPath()
          contextRef.current.moveTo(offsetX, offsetY)
          setIsDrawing(true)
  
      }
  
      const finishDrawing = () =&gt; {
          //console.log(contextRef.current)
          contextRef.current.closePath()
          setIsDrawing(false)
          //restore_array.push(contextRef.current.getImageData(0, 0,400,256+80))
          setIndex_array(index_array + 1)
          setRestore_Array((prevState) =&gt; { return [...prevState, contextRef.current.getImageData(0, 0,400,256+80)]})
          console.log(restore_array, restore_array.length)
          
      }
  
      const draw = ({nativeEvent}) =&gt; {
          if (!isDrawing) {
              return
          }
          const {offsetX, offsetY} = nativeEvent;
          contextRef.current.lineTo(offsetX, offsetY)
          contextRef.current.stroke()
      }
  
      const colourChange = (value) =&gt; {
          setPrColour(colour)
          setColour(value)
      }
  
      const thickChange = (event) =&gt; {
          setThick(event)
      }
        
        
      return (
      &lt;div&gt;
          &lt;div className=&quot;left&quot;&gt;
              
              
                  &lt;canvas className=&quot;canvas&quot; onMouseDown={startDrawing}
                          onMouseUp={finishDrawing}
                          onMouseMove={draw}
                          ref={canvasRef}/&gt;
          &lt;/div&gt;
          &lt;div className=&quot;right&quot;&gt;
              &lt;h5&gt;&lt;dt&gt;Chart Draw&lt;/dt&gt;&lt;/h5&gt;
              &lt;p&gt;Use your finger or your mouse to draw directly on the chart opposite.&lt;/p&gt;
  
              &lt;button className=&quot;draw&quot;&gt;Draw&lt;/button&gt;
              &lt;button className=&quot;select&quot;&gt;Select&lt;/button&gt;
  
              &lt;p&gt;&lt;dt&gt;Line thickness: {thick} &lt;/dt&gt; &lt;/p&gt;
              &lt;input className=&quot;slider&quot; type=&quot;range&quot; min=&quot;1&quot; max=&quot;19&quot; value={thick} class=&quot;slider&quot; id=&quot;myRange&quot; step=&quot;1&quot; onChange={(event)=&gt;thickChange(event.target.value)}&gt;&lt;/input&gt;
              
              &lt;button className='red' id='red'onClick={() =&gt; colourChange('red')}&gt;  &lt;/button&gt;
              &lt;button className='black' id='black'  onClick={() =&gt; colourChange('black')}&gt;  &lt;/button&gt;
              &lt;button className='yellow' id='rgba(204,153,0,255)' onClick={() =&gt; colourChange('rgba(204,153,0,255)')}&gt;  &lt;/button&gt;
              &lt;button className='blue' id='rgba(1,102,255,255)' onClick={() =&gt; colourChange('rgba(1,102,255,255)')}&gt;  &lt;/button&gt;
              &lt;button className=&quot;undoButton&quot; onClick={()=&gt;undoLast()}&gt; &lt;dt&gt; Undo/Back a step&lt;/dt&gt;&lt;/button&gt;
              &lt;button className=&quot;undoButton&quot; onClick={()=&gt;clearCanvas()}&gt; &lt;dt&gt; Clear canvas&lt;/dt&gt;&lt;/button&gt;
              &lt;button className=&quot;savecloseButton&quot;&gt; &lt;dt&gt;Save and Close&lt;/dt&gt;&lt;/button&gt;
  
          &lt;/div&gt;
      &lt;/div&gt;
      )
  
  }
  
  export default DrawCanvas;
  
  </code></pre>