Javascript 使用React钩子,如果其中一个';s的兄弟姐妹改变状态?
我已经使用array.map创建了一个组件网格。使用Javascript 使用React钩子,如果其中一个';s的兄弟姐妹改变状态?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我已经使用array.map创建了一个组件网格。使用console.log我可以看到,每当一个组件改变状态时,每个组件都在重新渲染。当网格为50x50时,速度会明显变慢 import React, { useState } from 'react'; function Cell({ cell, cellState, updateBoard }) { console.log('cell rendered') const CellStyle = { display: 'inli
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;
import React,{useState}来自“React”;
功能单元({Cell,cellState,updateBoard}){
console.log('cell rendered')
常量单元格样式={
显示:“内联块”,
宽度:“10px”,
高度:“10px”,
边框:“1px绿色实心”,
背景:cellState?“绿色”:“紫色”
};
函数handleClick(e){
更新板(单元格,!单元格状态)
}
返回(
)
}
函数App(){
console.log('board rendered')
const initialState=new Array(10.fill().map(()=>new Array(10.fill)(false));
let[board,setBoard]=使用状态(初始状态);
功能更新板(单元格,下一状态){
让tempBoard=[…board];
tempBoard[cell[0]][cell[1]]=nextState;
立根板(临时板)
}
返回(
{board.map((v,i,a)=>{
返回(
{v.map((w,j)=>
)}
)
}
)}
)
}
导出默认应用程序;
单击其中一个组件时,我希望父状态更新,单击的组件更新并重新渲染。由于其余组件没有更改,因此我不希望其他组件重新渲染。如何使用React钩子实现这一点?有几件事可以大大提高性能:
memo()
initialState
每个渲染-将其移动到上方(外部)
或在内部创建useState
作为函数(并使用const
而不是let
)最终解决方案:
import React, { useState, memo, useCallback } from "react";
import ReactDOM from "react-dom";
function Cell({ i, j, cellState, updateBoard }) {
console.log(`cell ${i}, ${j} rendered`);
const CellStyle = {
display: "inline-block",
width: "10px",
height: "10px",
border: "1px green solid",
background: cellState ? "green" : "purple"
};
function handleClick(e) {
updateBoard([i, j], !cellState);
}
return <span style={CellStyle} onClick={handleClick} />;
}
const MemoizedCell = memo(Cell);
function App() {
console.log("board rendered");
const [board, setBoard] = useState(() =>
new Array(10).fill().map(() => new Array(10).fill(false))
);
const updateBoard = useCallback(
(cell, nextState) => {
setBoard(oldBoard => {
let tempBoard = [...oldBoard];
tempBoard[cell[0]][cell[1]] = nextState;
return tempBoard;
});
},
[setBoard]
);
return (
<div style={{ display: "inline-block" }}>
{board.map((v, i, a) => {
return (
<div key={`Row${i}`} style={{ height: "12px" }}>
{v.map((w, j) => (
<MemoizedCell
key={`${i}-${j}`}
i={i}
j={j}
cellState={board[i][j]}
updateBoard={updateBoard}
/>
))}
</div>
);
})}
</div>
);
}
export default App;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React,{useState,memo,useCallback}来自“React”;
从“react dom”导入react dom;
功能单元({i,j,cellState,updateBoard}){
log(`cell${i},${j}rendered`);
常量单元格样式={
显示:“内联块”,
宽度:“10px”,
高度:“10px”,
边框:“1px绿色实心”,
背景:cellState?“绿色”:“紫色”
};
函数handleClick(e){
更新板([i,j],!cellState);
}
返回;
}
常量MemoizedCell=备忘录(单元格);
函数App(){
console.log(“提交的董事会”);
const[board,setBoard]=useState(()=>
新数组(10.fill().map(()=>新数组(10.fill)(false))
);
const updateBoard=useCallback(
(单元格,下一个状态)=>{
立根板(旧板=>{
让tempBoard=[…oldBoard];
tempBoard[cell[0]][cell[1]]=nextState;
返回临时板;
});
},
[黑板]
);
返回(
{board.map((v,i,a)=>{
返回(
{v.map((w,j)=>(
))}
);
})}
);
}
导出默认应用程序;
const rootElement=document.getElementById(“根”);
render(,rootElement);
您是否也知道如何消除eslint错误,该错误抱怨缺少依赖项board
('react-hooks/deps')@hyde您可以在const updateBoard
中添加board
作为[board,setBoard]
中添加board
。我更新了我的答案-现在它应该在eslint
中正确验证。这确实有助于消除关于useCallback和useMemo的许多混淆,从而提高性能。
const updateBoard = useCallback(
(cell, nextState) => {
setBoard(oldBoard => {
let tempBoard = [...oldBoard];
tempBoard[cell[0]][cell[1]] = nextState;
return tempBoard;
});
},
[setBoard]
);
const [board, setBoard] = useState(() =>
new Array(10).fill().map(() => new Array(10).fill(false))
);
import React, { useState, memo, useCallback } from "react";
import ReactDOM from "react-dom";
function Cell({ i, j, cellState, updateBoard }) {
console.log(`cell ${i}, ${j} rendered`);
const CellStyle = {
display: "inline-block",
width: "10px",
height: "10px",
border: "1px green solid",
background: cellState ? "green" : "purple"
};
function handleClick(e) {
updateBoard([i, j], !cellState);
}
return <span style={CellStyle} onClick={handleClick} />;
}
const MemoizedCell = memo(Cell);
function App() {
console.log("board rendered");
const [board, setBoard] = useState(() =>
new Array(10).fill().map(() => new Array(10).fill(false))
);
const updateBoard = useCallback(
(cell, nextState) => {
setBoard(oldBoard => {
let tempBoard = [...oldBoard];
tempBoard[cell[0]][cell[1]] = nextState;
return tempBoard;
});
},
[setBoard]
);
return (
<div style={{ display: "inline-block" }}>
{board.map((v, i, a) => {
return (
<div key={`Row${i}`} style={{ height: "12px" }}>
{v.map((w, j) => (
<MemoizedCell
key={`${i}-${j}`}
i={i}
j={j}
cellState={board[i][j]}
updateBoard={updateBoard}
/>
))}
</div>
);
})}
</div>
);
}
export default App;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);