I’m trying to render a chessboard using the react-chessboard component, but the component appears to be constantly rerendering, when I would expect it to render only once, or upon changes to the chessboard.
import React, { useState } from 'react';
import {Chessboard} from 'react-chessboard';
function ChessCollector() {
const ChessImage = React.memo(({ fen, id }) => {
return (
<Chessboard
position={fen}
id={id}
/>
);
});
return (
<div>
{<ChessImage
fen={'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'}
id={'1'}
/>}
</div>
);
}
export default ChessCollector;
Running locally, the chessboard renders, but opening the console, I see the following warning continually accruing at the rate of several times per second.
Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
at http://localhost:3000/static/js/bundle.js:9973:25
at http://localhost:3000/static/js/bundle.js:29:5
at div
at ChessOpeningsCollector
Using the ReactDevTools profiler, the component is constantly rerendering, but it’s unclear why to me. I’m not using setState inside useEffect (in my code at least) in this particular example, so the guidance from the warning message was not helpful.
I have reproduced the issue in a simple example (from a more complex application), to confirm there were no interactions with any other components causing this. Other questions with the same error have not been fruitful in debugging this particular example.
2
Answers
I think the issue probably lies in the
react-chessboard
library itself. I just checked their index page.https://github.com/Clariity/react-chessboard/blob/main/src/chessboard/index.tsx
is the file from the which the component is being exported.I just found this that could be causing maximum re-render issue,
so basically in line 44
metrics
variable is calculated with the help ofgetBoundingClientRect
method which returns an object containing x, y, top, bottom, left, right, width, height properties. Thismetrics
variable is used as a dependency to theuseEffect
slightly below in line 51. A statesetBoardContainerPos
is being set inside thisuseEffect
in line 47 which causes re-render because of whichmetrics
is calculated again anduseEffect
runs again. Sincemetrics
is an object which is given as a dependency, previous metrics is not as same as the current even when the property values are same.This should be fixed in 4.3.1.
https://github.com/Clariity/react-chessboard/releases/tag/v4.3.1