I want to update my 2d array with useState. It looks like:
[[null, null, null, null, null], [null, null, null, null, null], [null, null, null, null, null], [null, null, null, null, null], ...n]
You can imagine the array as rows and columns. Each column has the same value (null).
What I want is to assign the value I want to the first element of that 2d array every time a function is called.
I tried several ways to do this but unfortunately without success. I will share the code below. What is the shortest way to do this?
The code I tried:
const [data, setData] = useState(
Array.from({ length: 6 }, (v) => Array.from({ length: 5 }, (v) => null))
);
const addFunc = (e) => {
let value = e.target.value;
// first way
setData(
data.map(([...row]) => {
row.map((col) => {
if (col === null) {
return [...row, [...col, value]];
}
});
})
);
// second way
setData((val) => {
for (var i = 0; i < data.length; i++) {
for (var z = 0; z < data[i].length; z++) {
if (data[i][z] == null) {
return [...val, (val[i][z] = value)];
}
}
}
});
};
Since it sounds like you want to effectively "iterate" through the 2-d array data I suggest keeping a "count" or some current "index" value that is incremented each update. Create a utility function that converts this "count" into a computed "row" and "column" index that you want to update.
Example:
const [count, setCount] = useState(0);
const [data, setData] = useState(Array(6).fill(Array(5).fill(null)));
const countToRowCol = (count) => {
return {
row: Math.floor(count / 5), // 5 is the inner array length
col: count % 5
};
};
const addFunc = () => {
setData((data) =>
data.map((row, i) =>
i === countToRowCol(count).row
? row.map((el, j) => (j === countToRowCol(count).col ? myValue : el))
: row
)
);
setCount((c) => c + 1);
};
addFunc is just mapping the previous state's arrays into new array references for the matching row/column index, otherwise just shallow copies the previous state.