I'm trying to insert new elements in the array and update the state base on the array, but the problem after I update the state It doesn't get rendered in the component.
handleClick
function to add new element under the clicked element but it seems I failed in that as well.)setstate((pre) => { pre.splice(index + 1, 0, { id: 3, text: "xxx", autoFocus: true }); return pre; });
but didn't work as well.import React, { useState } from "react";
import "./styles.css";
export default function App() {
let elements = [
{ id: 0, text: "first", autoFocus: true },
{ id: 1, text: "second", autoFocus: true },
{ id: 2, text: "third", autoFocus: true }
];
const [state, setstate] = useState(elements);
function handChange(e) {
if (e.keyCode == 13) {
const x = state;
const index = x.findIndex((item) => item.id == e.target.id);
//i'm using autoFocus to move the focus (I-beam pointer) to the nex field.
//but i still get errors with it
// e.map((item) => Object.assign(item, { autoFocus: false }));
x.splice(index + 1, 0, { id: 3, text: "xxx", autoFocus: true });
console.log(state); // you can see this update probarly
setstate(x); // but when I update state sometimes it don't render othertimes it take a while before render.
}
}
return (
<div className="App">
{state.map((e) => (
// when I say it don't render I mean the e value don't get updated.
<div
focus={e.focus}
contentEditable="true"
id={e.id}
onKeyUp={handChange}
>
{e.text}
</div>
))}
</div>
);
}
on codesandbox
Instead of using
x.splice(index + 1, 0, { id: 3, text: "xxx", autoFocus: true });
setstate(x)
I replace it with this code
setstate((pre) => {
return [
...pre.slice(0, index + 1),
{ id: 3, text: "xxx", autoFocus: true },
...pre.slice(index + 1, state.length)
];
})
that return the elements before the element on the index index + 1
+ the new element + the elements after the element on the index index + 1
1
and you will a create a new element in the index 1+1
and after it, you will return the third element which is in the area between 1+1, 3
in which 3 is the length of the array....pre.slice(0, index + 1),
this return all elements before the element that you hit enter in it + the element that you hit enter in it.{ id: 3, text: "xxx", autoFocus: true },
this will create new elements after the previous elements...pre.slice(index + 1, state.length)
this will return the elements after the element where you hited enter (in case of there is no it will return nothing)