Реагировать: перезаписать массив другим массивом. Ошибка: Uncaught TypeError: ... не является функцией

В настоящее время я работаю над приложением todo в React. В функции handleClearTodos я хотел бы удалить все задачи со статусом: Готово. Для этого я прогоняю массив todos в этой функции и записываю все todos со статусом: Открыть в новый массив с именемcleanedTodos. В конце концов, когда я хочу перезаписать содержимое todos содержимым cleanTodos, я получаю следующее сообщение об ошибке:

Uncaught TypeError: currentTodos.forEach не является функцией

Это функция в компоненте Todo, которая отделяет задачи со статусом: Открыто от задач со статусом: Готово, сохраняет их в двух разных массивах и рендерит отдельно в функции рендеринга.

TodoTable.js (родительский компонент)

import React, {useState} from "react";
import { InputBar } from "./InputBar";
import { Todo } from "./Todo";


let currentTodos = [];

export const TodoTable = ({ mockTodos }) => {

    //Konstruktor
    if (mockTodos){
        currentTodos = mockTodos;
    }
   
    
    const [todos, setTodos] = useState(currentTodos);
    const [enterTodo, setEnterTodo] = useState('');


    //Enter Todo handler
    const handleEnterTodo = (event) => {
      setEnterTodo(event.target.value);
    };
  

    //Clear Todo handler
    const handleClearTodos = (event) => {
        let cleanedTodos = []

        todos.forEach((element, index) => {
            if (todos[index].status != 'open'){
                //console.info(todos[index])
                cleanedTodos.push(todos[index]);

 
            }
        });

        setTodos({ todos: cleanedTodos });
        
        console.info(typeof cleanedTodos);
        console.info(todos);
    }
    

    //Create Todo handler
    const handleCreateTodo = (event) => {

        //create new Todo
        const newTodo = {
            id: todos.length,
            describtion: enterTodo,
            status: 'open'
        };

        
        setTodos(todos => 
            [
                newTodo,
                ...todos
        
            ]
        );
    };
  
  

    return(
            <>
                <InputBar 
                    enterTodo = { enterTodo } 
                    handleEnterTodo = { handleEnterTodo } 
                    handleCreateTodo = { handleCreateTodo }
                    handleClearTodos= { handleClearTodos }
                />
                <Todo currentTodos = { todos } />
            </>      
    );
}

Todo.js (дочерний компонент)

import React from "react";

export const Todo = ({ currentTodos }) => {
    
    
    let openTodo = [];
    let doneTodo = [];
    // just for develope
    const lineBreak = <hr></hr>
    
    currentTodos.forEach((element, index) => {
        if (currentTodos[index].status == 'open'){
            
            let todoOpen = (
                
                <div className = "openTodos" key = { currentTodos[index].id.toString() }>
                    {currentTodos[index].describtion}
                    {/*Buttons*/}
                    {/*Buttons*/}
                </div>
            );
            openTodo = 
            [
                ...openTodo,
                todoOpen
            ]
        }
        else{
            
            let todoDone = (
                
                <div className = "doneTodos" key = { currentTodos[index].id.toString() }>
                    {currentTodos[index].describtion}
                    {/*Buttons*/}
                    {/*Buttons*/}
                </div>
            );
            doneTodo = 
            [
                ...doneTodo,
                todoDone
            ]
        }
        
      })
    
    return(
        <>
            {openTodo}
            {lineBreak}
            {doneTodo}
        </>
    );
}

InputBar (дочерний компонент)

import React from "react";
import { Button } from "./components/Button";

export const InputBar = ({ enterTodo, handleEnterTodo, handleCreateTodo, handleClearTodos}) => {
  console.info(enterTodo);
    return(
        <>
      <form>
        <input
          type='text'
          value = {enterTodo}
          onChange = {handleEnterTodo}
        />
        <Button lable= 'ADD'  disabled= { enterTodo == '' } onClick= { handleCreateTodo } />
        <Button lable= 'CLEAR' onClick= { handleClearTodos } />

      </form>
    </>
    );
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
21
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Функцию для каждого можно использовать для переменных типа Множество. Ваш реквизит текущийTodos не является массивом, вы устанавливаете его как объект:

setTodos({ todos: cleanedTodos });

Этот код возвращает ваши задачи:

console.info(todos.todos) // returning your cleanedTodos array

Но в вашем родительском компоненте вы инициализируете состояние как массив, поэтому он всегда должен быть массивом

Другие вопросы по теме

React useState обновляется в инструментах разработки, но не в консоли
React показывает отфильтрованное состояние при нажатии с помощью useReducer
Почему не работает сортировка в функции setSomething хука useState?
Есть ли способ добавить другое значение к ключу в объекте в React?
Как использовать вывод одного запроса axios в качестве зависимости для другого при рендеринге компонентов в React?
Реагировать на ввод, я определил состояние в начальное состояние, но все равно получаю предупреждение о смене неконтролируемого на контролируемый ввод
Как передать setState в другую функцию и использовать его для целевого значения из выбора материала-интерфейса и обработки изменения, ошибка «значение не определено»
Бесконечный цикл в реакции и socket.io
Снимите флажок (удалив) последний элемент в флажке и одновременно отметьте (добавьте) другой, сохраните непроверенное значение и добавьте другое отмеченное значение
Хук React useState всегда становится неопределенным при установке его в useEffect