Home > OS >  React function uses old state used when creating instance of subcomponent
React function uses old state used when creating instance of subcomponent

Time:09-16

I have a ToDo component and an Item component in my react app. I noticed that when I trigger my onDelete function from my Item component, it only has the tdList state variable in the state it was in when I created the item component. Why does this happen and how can I fix this issue.

function ToDo() {
    const [tdList, setTD] = useState([]);
    const [item, setItem] = useState("");
    const onDelete = (id) => {
        // console.log(id);
        console.log(tdList);
        for(let i=0; i<tdList.length; i  ){
            if (tdList[i].props.id == id){
                // setTD(tdList.splice(i, 1))
            }
        }
        // setTD(tdList.splice())
    };
    const onHandleSubmit = (event) => {
        event.preventDefault();
        setTD([...tdList, (<Item id={itemsAdded} item={item} delete={onDelete} />)]);
        setItem('');
        // console.log(tdList);
        itemsAdded  ;
    };
...more code...

CodePudding user response:

Don't put React components into state. It breaks the natural order of how they're supposed to work and can make the control flow that's been written very difficult to understand. Instead, into state, put only the values needed to create React components from later - and when returning from the component, create the components from that state.

For your code, you could do something like:

const [lastIdUsed, setLastIdUsed] = useState(-1); // use this instead of reassigning a non-React itemsAdded variable
const [tdData, setTdData] = useState([]);
const onDelete = (id) => {
    // use `.filter`, not `.splice` in React - don't mutate state
    setTdData(tdData.filter(tdItem => tdItem.id !== id));
};
const onHandleSubmit = (event) => {
    event.preventDefault();
    setTdData([...tdData, { id: lastIdUsed   1, item }]);
    setItem('');
    setLastIdUsed(lastIdUsed   1);
};
const tds = tdData.map(
    tdItem => <Item id={tdItem.id} item={tdItem.item} delete={onDelete} />
);

And then with the tds, return them or interpolate them into the JSX at the end.

Only create components right before you're going to return them.

  • Related