Задать вопрос
@Dias747
Студент который мечтают стат программистом

Как сделать фильтрацию?

Как сделать фильтрацию на реакте?

todos приходит из компонента App, не могу присвоит значение в State всегда получаю undefined.
Может это из-за асинхронности?

const [newTodos, setNewTodos] = useState(todos);

Хотелось бы с помощью state сделать фильтрацию, сортировку и поиск.

export const TodoContext = createContext();

function App() {
    const [todos, setTodos] = useState([]);

    function addTask(task) {
        const newTodos = [task, ...todos];

        setTodos(newTodos.sort((a, b) => a.checked - b.checked));
    }

    function deleteTask(index) {
        setTodos(todos.filter((_, inx) => inx !== index));
    }

    function onChecked(inx) {
        const newTodos = todos.map((todo, i) => {
            if (i === inx) {
                return {
                    ...todo,
                    checked: !todo.checked,
                };
            }

            return todo;
        });

        setTodos(newTodos.sort((a, b) => a.checked - b.checked));
    }

    useEffect(() => {
        const localTodos = localStorage.getItem("todos") || [];

        setTodos(JSON.parse(localTodos));
    }, []);

    useEffect(() => {
        localStorage.setItem("todos", JSON.stringify(todos));
    }, [todos]);

    return (
        <TodoContext.Provider value={todos}>
            <div className="todos container">
                <Form addTask={addTask} />
                <Todos deleteTask={deleteTask} onChecked={onChecked} />
            </div>
        </TodoContext.Provider>
    );
}


const Todos = ({ deleteTask, onChecked }) => {
    const todos = useContext(TodoContext);

    return (
        <div className="todos__tasks ">
            <form className="todos__form">
                <input className="todos__form-search" type="search" placeholder="Поиск" />
            </form>
            <div className="todos__header">
                <div className="todos__sorts">
                    <span className="todos__sorts-item">по названию</span>
                    <span className="todos__sorts-item">по времени</span>
                </div>

                <select className="todos__filter">
                    <option className="todos__filter-item" value="all">
                        Все
                    </option>
                    <option className="todos__filter-item" value="checked">
                        Выполненные
                    </option>
                    <option className="todos__filter-item" value="notChecked">
                        Не выполненные
                    </option>
                </select>
            </div>

            {todos.length !== 0 ? (
                todos.map((todo, inx) => (
                    <Task
                        key={inx}
                        inx={inx}
                        task={todo}
                        deleteTask={deleteTask}
                        onChecked={onChecked}
                    />
                ))
            ) : (
                <h3 style={{ marginTop: "30px" }}>Задачи пока нету</h3>
            )}
        </div>
    );
};
  • Вопрос задан
  • 144 просмотра
Подписаться 1 Простой 3 комментария
Решения вопроса 1
Aetae
@Aetae Куратор тега JavaScript
Тлен
Чтоб сделать фильтрацию просто делаешь так:
const [selected, setSelected] = useState('all');

  let filterdTodos;
  switch(selected) {
    case 'all':
      filterdTodos = todos;
      break;
    case 'checked':
      filterdTodos = todos.filter(t => t.checked);
      break;
    case 'notChecked':
      filterdTodos = todos.filter(t => !t.checked);
      break;
  }

Или так, с оптимизацией:
const [selected, setSelected] = useState('all');

  const filterdTodos = useMemo(() => {
    switch(selected) {
      case 'all':
        return todos;
      case 'checked':
        return todos.filter(t => t.checked);
      case 'notChecked':
        return todos.filter(t => !t.checked);
    }
  }, [selected, todos])

<select className="todos__filter" onChange={(event) =>setSelected(event.target.value)}>
...
{filterdTodos.map(...)}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы