我已经使用array.map创建了一个组件网格。使用console.log
,我可以看到每当一个组件更改状态时,每个组件都会重新渲染。当我有50x50的网格时,这会变得很慢。
import React, { useState } from 'react';
function Cell({ cell, cellState, updateBoard }) {
console.log('cell rendered')
const CellStyle = {
display: 'inline-block',
width: '10px',
height: '10px',
border: '1px green solid',
background: cellState ? 'green' : 'purple'
};
function handleClick(e) {
updateBoard(cell, !cellState)
}
return (
<span
style={CellStyle}
onClick={handleClick}
/>
)
}
function App() {
console.log('board rendered')
const initialState = new Array(10).fill().map(() => new Array(10).fill(false));
let [board, setBoard] = useState(initialState);
function updateBoard(cell, nextState) {
let tempBoard = [...board];
tempBoard[cell[0]][cell[1]] = nextState;
setBoard(tempBoard)
}
return (
<div style={{ display: 'inline-block' }}>
{board.map((v, i, a) => {
return (
<div
key={`Row${i}`}
style={{ height: '12px' }}
>
{v.map((w, j) =>
<Cell
key={`${i}-${j}`}
cell={[i, j]}
cellState={board[i][j]}
updateBoard={updateBoard}
/>
)}
</div>
)
}
)}
</div>
)
}
export default App;
当我单击其中一个组件时,我希望更新父状态,并希望单击的组件更新并重新呈现。由于其余组件未更改,因此我不希望其他组件重新渲染。如何使用React-Hooks完成此操作?
答案 0 :(得分:2)
几乎没有什么可以大大提高性能的。
memo()
const MemoizedCell = memo(Cell);
/*...*/
<MemoizedCell
/*...*/
/>
<Cell />
的新引用您正在传递cell={[i, j]}
-每次调用它都会创建新数组(!),这意味着Cells的属性已被更改-为什么那时不再次渲染? / p>
与传递updateBoard={updateBoard}
相同-每次<App />
渲染时您都在创建新函数。您需要记住它,并在功能中使用旧状态。
const updateBoard = useCallback(
(cell, nextState) => {
setBoard(oldBoard => {
let tempBoard = [...oldBoard];
tempBoard[cell[0]][cell[1]] = nextState;
return tempBoard;
});
},
[setBoard]
);
initialState
-将其移到<App />
上方(外部)或在useState
内部创建为函数(并使用const
而不是{{1} })。let
最终解决方案:
const [board, setBoard] = useState(() =>
new Array(10).fill().map(() => new Array(10).fill(false))
);