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

Ссылка скопирована
1 ответ

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

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>     ); }

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>     ); };

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> ); };

Дополнительно:

Очистите код от лишнего, приведите код App (тоже желательно без ненужных элементов)

  • const localTodos = localStorage.getItem("todos") || []; -> const localTodos = localStorage.getItem("todos") || '[]';

    const localTodos = localStorage.getItem("todos") || []; -> const localTodos = localStorage.getItem("todos") || '[]';

    В остальном всё должно работать.

  • Да, приведённый кусок кода абсолютно рабочий, однако прочитав твой вопрос ещё раз я так понял что ты хочешь сделать фильтрацию по какому-то значению и у тебя не получается. Однако ты почему-то не включил код того что не получается в пример * facepalm*.
  • Чтоб сделать фильтрацию просто делаешь так:

    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'); 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])

    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(...)}

    <select className="todos__filter" onChange={(event) =>setSelected(event.target.value)}> ... {filterdTodos.map(...)}

    • Сочнейший сок прям, все заработал здесь я понял как работает рендер и его преимущества, а как взять данные из контекста и сохранить в стеит? или так нельзя?
      Просто помимо фильтрации есть еще сортировка и поиск, а массив просто не рендерится после поиска или сортировки.
    • Диас Галымбек, ты всё-таки что-то через зад пытаешься сделать. Контекст надо использовать, а на сохранять локально.
      Возможно ты хочешь изменять контекст изнутри - тогда просто пробрасывавший в него вышестоящий setState и вызывай когда надо.

      Если очень хочется то както-так:

      const todos = useContext(TodoContext); const [localTodos, setLocalTodos] = useState(todos);  useEffect(() => setLocalTodos(todos), [todos]);

      const todos = useContext(TodoContext); const [localTodos, setLocalTodos] = useState(todos); useEffect(() => setLocalTodos(todos), [todos]);

      Но это плохо.

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Юрий Linux Ответ

    Для реализации фильтрации на веб-сайте можно использовать различные методы, в зависимости от требований проекта. Ниже приведен пример использования PHP для создания фильтра на странице.

    Для начала создадим форму на странице, через которую пользователь будет выбирать параметры для фильтрации:

     
     
     
            Category 1
            Category 2
            Category 3

    Category 1 Category 2 Category 3

    Затем на серверной стороне обработаем данные формы и выполним фильтрацию:

    <?php
    // Получаем данные из формы
    $search = isset($_GET['search']) ? $_GET['search'] : '';
    $category = isset($_GET['category']) ? $_GET['category'] : '';
    
    // Выполняем запрос к базе данных с учетом выбранных параметров
    $query = "SELECT * FROM products WHERE 1=1";
    if (!empty($search)) {
        $query .= " AND name LIKE '%$search%'";
    }
    if (!empty($category)) {
        $query .= " AND category_id = '$category'";
    }
     
    // Выполняем запрос
    $result = mysqli_query($connection, $query);
     
    // Выводим результаты
    while ($row = mysqli_fetch_assoc($result)) {
        echo $row[&#039;name&#039;] . &quot;<br>";
    }
    ?&gt;

    &lt;?php // Получаем данные из формы $search = isset($_GET[&#039;search&#039;]) ? $_GET[&#039;search&#039;] : &#039;&#039;; $category = isset($_GET[&#039;category&#039;]) ? $_GET[&#039;category&#039;] : &#039;&#039;; // Выполняем запрос к базе данных с учетом выбранных параметров $query = &quot;SELECT * FROM products WHERE 1=1&quot;; if (!empty($search)) { $query .= &quot; AND name LIKE &#039;%$search%&#039;&quot;; } if (!empty($category)) { $query .= &quot; AND category_id = &#039;$category&#039;&quot;; } // Выполняем запрос $result = mysqli_query($connection, $query); // Выводим результаты while ($row = mysqli_fetch_assoc($result)) { echo $row[&#039;name&#039;] . &quot;<br>"; } ?&gt;

    В данном примере мы получаем данные из формы, строим запрос к базе данных с учетом выбранных параметров и выводим результаты фильтрации. Не забудьте подставить свои данные для подключения к базе данных.

    Таким образом, вы можете создать простой фильтр на своем веб-сайте с использованием PHP.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно