Reputation: 99
I have a canvas which has grid data of 500 rows X 500 cols. I am trying to update few particular cells in React state, once react state is updated whole canvas is re-created and rendered. Is there any better way to update part of canvas? Below is the flow of component
componentDidMount()
and save response in state.Upvotes: 1
Views: 3673
Reputation: 576
I don't believe that the number of items in the canvas is the issue. I'm guessing that the issue is that you need to update the items in the correct way. Here's an example using Hooks of how to update just parts of the canvas that are changing without changing everything. Obviously it would need to be adapted to your specific instance, but it should give you a direction on how you could do it.
function Canvas(props) {
var item = 0;
// pos is the item in the table that's going to be updated
const [pos, setPos] = React.useState(0);
//sample data
const [A,setA] = React.useState([
{data:"N", id:1},{data:"N",id :2},{data:"N",id :3},{data:"N",id :4}
]);
const totalitems = A.length;
const canvasRef = React.useRef(null)
function HandleClick() {
let newArray = [...A];
item=Math.floor(Math.random()*totalitems);
// toggle between letters
newArray[item].data == "N" ? newArray[item].data = "H" : newArray[item].data = "N" ;
setA(newArray); // set the entry in the array to the new letter
setPos(item);
};
const tabledraw = ctx => {
// The following line clears the whole canvas
// ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
ctx.fillStyle = '#000000';
// Clear only part of the canvas that corresponds to the size
// of the text that is being replaced
ctx.clearRect(pos*50, 0,50, 100);
ctx.font = "30px Arial";
// translate the position of the start of the canvas to where the
// character that is changing is
ctx.translate(pos*50,0);
ctx.fillText(A[pos].data, 0, 80);
// Translate the canvas back to its original position
ctx.translate(-pos*50,0);
}
React.useEffect(() => {
const canvas = canvasRef.current
const context = canvas.getContext('2d')
tabledraw(context)
}, [tabledraw])
return(
<>
<canvas ref={canvasRef} {...props}/>
<button onClick={HandleClick}>Change</button>
</>
)
}
Upvotes: 1