簡體   English   中英

使用 React useState 鈎子時無法獲取更新的 state

[英]Unable to get the updated state when using React useState hook

我正在嘗試執行 state 更改,之后我想發出 API 請求。 但是由於 useState 是異步的,我不能那樣做。 我嘗試使用useEffect()掛鈎,但無法找到已更改的確切數組元素。

toggleCompleted()中,我得到了setTasks updatedTask異步的。

應用程序.js

import { useState, useEffect } from 'react'

const App = () => {
    const [tasks, setTasks] = useState([])

    const toggleCompleted = id => {
        setTasks(
            tasks.map(task => {
                return task.id === id
                    ? { ...task, isCompleted: !task.isCompleted }
                    : task
            })
        )

        // This will get the old value
        const updatedTask = tasks.find(task => task.id === id)
        
        // PUT request here
        fetch(`${api_url}/tasks/${id}`, {
             method: 'PUT',
             body: JSON.stringify(updatedTask)
        })
    }
}

export default App

我也嘗試使用useEffect掛鈎,但我得到的是整個tasks數組,而不是更新的單個任務,因此我無法使用它向我的后端 API 發出PUT請求。

useEffect(() => {
  // unable to get the exact one task that was updated
}, [tasks])

為什么不這樣做:

import { useState, useEffect } from 'react'

const App = () => {
    const [tasks, setTasks] = useState([])

    const toggleCompleted = id => {
        let updatedTask = tasks.filter(task => task.id === id)
        updatedTask.isCompleted = !updatedTask.isCompleted

        // PUT request here
        fetch(`${api_url}/tasks/${id}`, {
             method: 'PUT',
             body: JSON.stringify(updatedTask)
        })

        setState(tasks.map(task => task.id === id ? updatedTask : task))
    }
}

export default App

這應該可以解決您的問題。
基本上,我們捕獲要更新的任務,根據需要對其進行操作,然后最后設置 state。

我最終將我的代碼重構到我第一次獲取和更新用於更新 state 和進行 API 調用的元素的位置。

const toggleReminder = id => {
    let updatedTask = tasks.find(task => task.id === id)
    updatedTask.isCompleted = !updatedTask.isCompleted

    setTasks(
        tasks.map(task => {
            return task.id === id
                ? updatedTask
                : task
        })
    )

    fetch(`${api_url}/tasks/${id}`, {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(updatedTask)
    })
}

試試這個

import { useState, useEffect } from 'react'

const App = () => {
    const [tasks, setTasks] = useState([])

    const toggleCompleted = async (id) => {
        const currentTask = tasks.find(task => task.id === id);
        const updatedTask = {...currentTask, isCompleted: !currentTask.isCompleted}; 
        
        await fetch(`${api_url}/tasks/${id}`, {
             method: 'PUT',
             body: JSON.stringify(updatedTask)
        });

        setTasks(tasks.map(task => task.id === id?updatedTask :task));
    }
}

export default App

您可以使用普通的 function 而不是 async / await 並將 setTasks 放入。然后,但我認為它更簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM