我正在尝试使用react-chessboard组件渲染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;
在本地运行,棋盘会渲染,但是打开控制台,我看到以下警告以每秒几次的速度不断出现。
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
使用 ReactDevTools 分析器,组件会不断重新渲染,但我不清楚为什么。在这个特定的示例中,我没有在 useEffect 中使用 setState (至少在我的代码中),因此警告消息中的指导没有帮助。
我在一个简单的示例(来自更复杂的应用程序)中重现了该问题,以确认没有与任何其他组件的交互导致此问题。其他具有相同错误的问题在调试这个特定示例时没有取得成果。
我认为问题可能出在
react-chessboard
库本身。我刚刚检查了他们的索引页。
https://github.com/Clariity/react-chessboard/blob/main/src/chessboard/index.tsx
是从中导出组件的文件。
我相信这就是问题所在
所以基本上在第 44 行 metrics
变量是在 getBoundingClientRect
方法的帮助下计算的,该方法返回一个包含 x、y、顶部、底部、左、右、宽度、高度属性的对象。这个 metrics
变量用作第 51 行稍下方的 useEffect
的依赖项。在第 47 行的这个 setBoardContainerPos
内部设置了状态 useEffect
,这会导致重新渲染,因为计算 metrics
再次运行,useEffect
再次运行。由于 metrics
是作为依赖项给出的对象,因此即使属性值相同,先前的指标也与当前的指标不同。