Не удается получить значение из useState, когда this.state работает - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь создать список задач, используя данные из базы данных Firebase. В следующем коде запускается функция с именем handleChange, которая запускается, когда пользователь устанавливает или снимает флажок. В зависимости от того, установлен он или нет & ID флажка, при щелчке он изменяется на true или false. Я попытался воспроизвести этот учебник в REACT & Google Firebase, но безуспешно.

    const [allTodos, setTodos] = useState([])  
    useEffect(() => {
        const database = firebase.database().ref();
        database.on("value", logData)  
    }, []) 

    function logData(rowData) {    
        setTodos(rowData.val())
    } 
    function handleChange(id) {
        console.log(id);
        setTodos(prevState => {
            const updatedTodos = prevState.allTodos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return {
                allTodos: updatedTodos
            }

        })   
    }

Выдает эту ошибку: TypeError: Cannot read property 'map' of undefined

  17 | function handleChange(id) {
  18 |     console.log(id);
  19 |     setTodos(prevState => {
> 20 |         const updatedTodos = prevState.allTodos.map(todo => {
     | ^  21 |             if (todo.id === id) {
  22 |                 todo.completed = !todo.completed
  23 |             }

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

prevState.allTodos не определено, поскольку prevState не является объектом со свойством allTodos ... prevState само по себе является allTodos.

Попробуйте это:

    const [allTodos, setTodos] = useState([])  
    useEffect(() => {
        const database = firebase.database().ref();
        database.on("value", logData)  
    }, []) 

    function logData(rowData) {    
        setTodos(rowData.val())
    } 
    function handleChange(id) {
        console.log(id);
        setTodos(prevTodos => {
            const updatedTodos = prevTodos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return updatedTodos // <-- return the todos, not an object
        })   
    }
0 голосов
/ 04 мая 2020

Не уверен из кода, что происходит с состоянием и когда вызывается обработчик изменения, но наверняка у состояния нет никакого allTodos в handle change времени, и лучше обновлять состояние независимо от prevState. давайте отделим обновление состояния следующим образом и посмотрим, что произойдет

const updatedTodos = allTodos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
            });
 setTodos(updatedTodos);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...