[英]useEffect not re-run after updating state of 2D Array matrix
我有一個帶有數組初始值的useState
,並且我有一個更改數組的算法。
我console.log
編輯了matrix
,它發生了變化,但是連接到它的useEffect
依賴於useState
的matrix
,不會像我需要的那樣更新我的組件。
當我開始在 VS Code 中輸入時,它只會更改並重新呈現。
我試圖將setMatrix
從useState
切換過來,但它沒有用。
import React, {MouseEvent, useEffect, useState} from 'react'
const TwoDArray = () => {
let twodarray:number[][] = [
[1,1,1,1],
[1,0,1,1],
[1,1,0,1],
[0,0,0,1]
]
const [matrix, setMatrix] = useState(twodarray)
const setMatrixZeros = (matrix: number[][], ) => {
let col0: number = 1, rows: number = matrix.length, cols = matrix[0].length
for (let i: number = 0; i < rows; i++) {
if (matrix[i][0] == 0) col0 = 0
for (let j: number = 1; j < cols; j++)
if(matrix[i][j]==0) matrix[i][0] = matrix[0][j] = 0
}
for (let i: number = rows - 1; i >= 0; i--) {
for (let j: number = cols - 1; j >= 1; j--) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0
}
if(col0==0) matrix[i][0] = 0
}
}
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
setMatrixZeros(matrix)
}
useEffect(() => {
}, [matrix]); // Only re-run the effect if matrix changes
console.log(matrix)
return (
<div className="twodarray">
<div className="matrix">
{ matrix.map((item, index) => {
return <div key={index} className='box-container'>
{item.map((i, idx) =>
<input type='text' key={idx} className='box' value={ i} readOnly/>)}</div>
})}
</div>
<button onClick={handleClick }>Set Matrix Zeroes</button>
</div>
)
}
export default TwoDArray
React 不跟蹤深層狀態突變(例如與 Vue 3 不同)。
您必須使用setMatrix
設置狀態操作顯式更改狀態 + 確保新狀態是不同的引用,例如使用淺克隆(通常使用展開運算符):
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
setMatrixZeros(matrix)
// Create a new reference
const newMatrix = [...matrix]
// Make sure to use the setter
setMatrix(newMatrix)
}
如果沒有新的引用,依賴數組將看不到狀態變化, useEffect
也不會重新運行。
據我了解,最大的問題是代碼直接修改狀態,例如: matrix[i][0] = matrix[0][j]
,而不是使用setMatrix(newMatrix)
。
如果您使用已經修改的矩陣調用setMatrix(Matrix)
(正如我猜您在切換到useEffect
之前所做的那樣),它不會注意到更改並且不會重新呈現頁面。
下面是您的代碼的一個有效的修改版本,它只是交換了 1 和 0 的位置。 我真的不明白你的setMatrixZeroes()
應該做什么,所以我將名稱更改為 changeMatrix changeMatrix()
,以免將它與狀態設置功能混淆,你可以修改它以適應你的功能'再之后。
const TwoDArray = () => {
let initMatrix:number[][] = [
[1,1,1,1],
[1,0,1,1],
[1,1,0,1],
[0,0,0,1]
]
const [matrix, setMatrix] = useState(initMatrix)
const changeMatrix = () => {
const newMatrix:number[][] = []
for(let row of matrix){
let newRow:number[] = []
for(let number of row){
number === 0
? newRow.push(1)
: newRow.push(0)
}
newMatrix.push(newRow)
}
setMatrix(newMatrix)
}
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
changeMatrix()
}
return(
// ... tsx-code ... //
)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.