【问题标题】:How can i prevent Re-rendering of functional child element如何防止重新渲染功能性子元素
【发布时间】:2022-07-05 15:32:03
【问题描述】:

在 React js 上创建井字游戏时。每当我单击单个图块时,它也会重新渲染所有其他图块。

const Game = () => {
const [xIsNext, setXIsNext] = useState(true);
const [stepNumber, setStepNumber] = useState(0);
const [history, setHistory] = useState([{ squares: Array(9).fill(null) }]);
const updatedHistory = history;
const current = updatedHistory[stepNumber];
const winner = CalculateWinner(current.squares);
const move = updatedHistory.map((step, move) => {
const desc = move ? `Go to # ${move}` : "Game Start";
const jumpTo = (step) => {
  setStepNumber(step);
  setXIsNext(step % 2 === 0);
};
return (
  <div key={move}>
    <button className="btninfo" onClick={() => jumpTo(move)}>{desc}</button>
  </div>
);
});
let status;
if (winner) {
status = `Winner is ${winner}`;
} else {
status = `Turn for Player ${xIsNext ? "X" : "O"}`;
}
const handleClick = (i) => {
const latestHistory = history.slice(0, stepNumber + 1);
const current = latestHistory[latestHistory.length - 1];
const squares = current.squares.slice();
const winner = CalculateWinner(squares);
if (winner || squares[i]) {
  return;
}
squares[i] = xIsNext ? "X" : "O";
setHistory(history.concat({ squares: squares }));
setXIsNext(!xIsNext);
setStepNumber(history.length);
};
const handleRestart = () => {
setXIsNext(true);
setStepNumber(0);
setHistory([{ squares: Array(9).fill(null) }]);
};
return (
<div className="game">
  <div className="game-board">
    <div className="game-status">{status}</div>
    <Board onClick={handleClick} square={current.squares} />
  </div>
  <div className="game-info">
    <button className="btninfo" onClick={handleRestart}>Restart</button>
    <div>{move}</div>
  </div>
</div>
);
};
export default Game;

const CalculateWinner = (squares) => {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[b] === squares[c]) {
  return squares[a];
}
}
return null;
};

传递参数的Board组件是

   const Board = (props) => {
   const renderSquare = (i) => {
   return <Square value={props.square[i]} onClick={() => props.onClick(i)} />;
   };
   return (
   <div>
   <div className="border-row">
    {renderSquare(0)}
    {renderSquare(1)}
    {renderSquare(2)}
   </div>
   <div className="border-row">
    {renderSquare(3)}
    {renderSquare(4)}
    {renderSquare(5)}
   </div>
   <div className="border-row">
    {renderSquare(6)}
    {renderSquare(7)}
    {renderSquare(8)}
   </div>
    </div>
   );
};
export default Board;

这会导致下面提到的单个 Square 组件,如果我们单击单个图块,它将为所有图块重新渲染。

 const Square = (props) => {
return (
<button className="square" onClick={props.onClick}>
  {props.value}
</button>
);
};
export default Square;

我尝试在handleClick函数上使用useCallback,并将第二个参数保留为空数组,然后它也不起作用。

如何防止重新渲染其他图块?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    如果 React 组件的父组件重新渲染,它将导致子组件重新渲染,除非该组件使用 React.memo 优化或 shouldComponentUpdate 生命周期方法处理此问题。

    由于您的组件是功能组件,因此只需在导出时执行此操作:

    export default React.memo(Square);
    

    【讨论】:

      猜你喜欢
      • 2021-02-14
      • 2021-09-29
      • 2020-03-09
      • 2021-06-08
      • 1970-01-01
      • 2020-03-27
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多