反应钩子使用状态与数组导致缺少渲染调用



我有以下代码:

function MyComponent( props ) {
let arrSize = 5;
const [arr, setArr] = useState( () => {
let initial = new Array(arrSize);
for(let i=0; i<arrSize; i++) initial.push({ foo: 'foo', bar: 'bar'});
return initial;
});
mouseEventCallback = (e) => {
// ...
let tmp = arr;
// ...
setArr( tmp );
}
let cmp = [];
for(let i=0; i<arrSize; i++) {  
cmp.push( <span key={i} className={arr[i].foo}></span> );
}
return (
<div>
{cmp}
</div>
)
}

当鼠标回调调用几次时,我遇到了一个问题:状态参数更改正常(使用 react 组件检查 Chrome 网络浏览器中的选项卡(,但具有此状态的 DOM 元素并未全部重新渲染 - 其中一些具有旧状态。

当我添加虚拟状态时 - 一切正常:

function MyComponent( props ) {
let arrSize = 5;
const [arr, setArr] = useState( () => {
let initial = new Array(arrSize);
for(let i=0; i<arrSize; i++) initial.push({ foo: 'foo', bar: 'bar'});
return initial;
});
const [dummy, setDummy] = useState(0);
mouseEventCallback = (e) => {
// ...
let tmp = arr;
// ...
setArr( tmp );
setDummy( Math.rand() );
}
let cmp = [];
for(let i=0; i<arrSize; i++) {  
cmp.push( <span key={i} className={arr[i].foo}></span> );
}
return (
<div dataTest={dummy}>
{cmp}
</div>
)
}

我如何改进我的代码并以正确的方式解决我的问题?

您的组件不会在 setArr(tmp( 上重新渲染,因为 "tmp" 变量引用与 "arr" 变量相同的数组。相同的引用意味着它们指向内存中的相同事物,因此当 react 在旧状态和新状态之间执行比较时.tmp它们返回相同的内容即 === arr 返回 true。如果旧状态 = 新状态组件不会重新渲染。所以为了重新渲染;使"tmp"指向与"arr"具有相同数据的新数组。您可以使用 ES6 跨页运算符。

更改:让 tmp = arr; 收件人:让 tmp = [...arr];

let a = [1, 2, 3];
let b = a;
let c = [...a]; // ES6 Spread Operator
a === b; // returns true
a === c; // returns false

正确的代码:

function MyComponent( props ) {
let arrSize = 5;
const [arr, setArr] = useState( () => {
let initial = new Array(arrSize);
for(let i=0; i<arrSize; i++) initial.push({ foo: 'foo', bar: 'bar'});
return initial;
});
mouseEventCallback = (e) => {
// ...
let tmp = [...arr];
// ...
setArr( tmp );
}
let cmp = [];
for(let i=0; i<arrSize; i++) {  
cmp.push( <span key={i} className={arr[i].foo}></span> );
}
return (
<div>
{cmp}
</div>
)
}

相关内容

  • 没有找到相关文章

最新更新