简体   繁体   中英

React SetState not adding new objects to array of objects

This code is supposed to add new tasks to the state and keep the previous objects, past posts on this have lead to the same issue that it just wont be added.

function App() {

    var [tasks, setTasks] = useState([

        {
            id: uuidv4(),
            text: 'Meeting at place',
            specify: 'todo',
        },
        {
            id: uuidv4(),
            text: 'Shopping',
            specify: 'inprogress',

        },
        {
            id: uuidv4(),
            text: 'Appointment',
            specify: 'complete',

        },
    ])

    //Add Task
    const newTask = (text) => {
        const id = uuidv4();
        var specify = 'todo'
        const makeTask = { id, ...text, specify }
        console.log(makeTask)
        console.log([...tasks, makeTask])
        setTasks(tasks => [...tasks, makeTask])
        console.log(tasks)

    }

when I log what's inside the set function it shows all 4 but it doesnt get saved into tasks

My drag and drop function which filters by id works with the predefined object literals but not new added tasks, and instead returns undefined with new tasks.

Edit: useEffect was solution to correctly show my state for those with same issue. My issue was more complex due to react dnd and found solution here React Hooks: Can't access updated useState variable outside useEffect? .

React setState hook is executed asynchronously so after updating, you cannot access the updated state in that function. if you want to access to updated tasks, you can use useEffect hook:

const newTask = (text) => {
    const id = uuidv4();
    var specify = 'todo'
    const makeTask = { id, text, specify }
    setTasks(tasks => [...tasks, makeTask])
}


useEffect(() => {
    console.log(tasks);
}, [tasks]);

You may want to give use-immer a go to handle object/array states.

The useImmer hook behaves the same as useState hook and updates your object states seamlessly.

This is your code below but with useImmer

import { useImmer } from "use-immer";

function App() {
  const [tasks, updateTasks] = useImmer([

        {
            id: uuidv4(),
            text: 'Meeting at place',
            specify: 'todo',
        },
        {
            id: uuidv4(),
            text: 'Shopping',
            specify: 'inprogress',

        },
        {
            id: uuidv4(),
            text: 'Appointment',
            specify: 'complete',

        },
    ])

    //Add Task
    const newTask = (text) => {
        const id = uuidv4();
        const specify = 'todo'
        const makeTask = { id, ...text, specify }
        updateTasks(draft => draft.push(metaTask));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM