Ваш компонент не выполняет рендеринг после setArr (tmp), потому что переменная "tmp" ссылается на тот же массив, что и переменная "arr". Одна и та же ссылка означает, что они указывают на одну и ту же вещь в памяти, поэтому, когда реакция выполняет сравнение между старым состоянием и новым состоянием, они возвращают одно и то же, то есть tmp === arr возвращает true. Если старое состояние = новое состояние, компонент не перерисовывается. Итак, для того, чтобы перерисовать;сделать так, чтобы "tmp" указывал на новый массив с теми же данными, что и "arr". Вы можете использовать оператор распространения ES6.
Изменение: let tmp = arr;To: let 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>
)
}