React - проблемы с фильтрацией извлеченных данных из глобального контекста - PullRequest
1 голос
/ 11 июля 2020

У меня есть простое приложение, показывающее товары с ценами на них. Я создал глобальный контекст как свое глобальное состояние. Я пытаюсь создать компонент фильтра, где я могу фильтровать элементы, которые я получаю из контекста, - фильтруя элементы по ценам (сортировать по наивысшему или наименьшему).

Вот мой компонент фильтра:

import * as React from "react";

const Filter = ({ updateFilter }) => {
  const [state, setState] = React.useState("");

  const handleChange = (prop, value) => {
    setState({
      [prop]: value,
    });
  };

  return (
    <div>
        <form onChange={() => updateFilter(state)} noValidate>
          <select
            value={state.sortOrder}
            onChange={(event) =>
              handleChange("sortItems", event.target.value)
            }
          >
            <option value="">Choose...</option>
            <option value="highest">Highest</option>
            <option value="lowest">Lowest</option>
          </select>
        </form>
    </div>
  );
};

export default Filter;

Вот домашний компонент, который использует указанный выше компонент фильтра:

import React, { useContext, useState } from "react";
import Filter from "./shared/Filter";
import Card from "./Card";
import { GlobalContext } from "../context/GlobalState";

const defaultState = {
  sortItems: "",
};

const Home = () => {
  const { items } = useContext(GlobalContext);
  const [filter, setFilter] = useState(defaultState);

  const applyFilter = (items, filter) => {
    const { sortItems } = filter;
    let data = items;

    if (sortItems) {
      if (sortItems === "") {
        return data;
      }
      if (sortItems === "highest") {
        data = data.sort((a, b) => b.price - a.price);
      }
      if (sortItems === "lowest") {
        data = data.sort((a, b) => a.price - b.price);
      }
    }
    return data;
  };

  const updateFilter = (filter) => {
    setFilter(filter);
  };

  const filteredItems = applyFilter(items, filter);

  return (
    <React.Fragment>
      <Filter updateFilter={updateFilter} />
      <div>
        {filteredItems.map((listing) => (
          <Link
            to={`items/${item.id}`}
          >
            <Card key={listing.id} listing={listing} />
          </Link>
        ))}
      </div>
    </React.Fragment>
  );  
};

export default Home;

Для справки - items из моего глобального контекста возвращает массив таких элементов:

[
  {
    "id": "1",
    "name": "Item A",
    "category": "A",
    "price": 10000 
  },
  ...
  ..
  ..
]

Проблема, с которой я столкнулся, теперь заключается в том, что когда я впервые выбрал фильтр, например - Highest, и я утешал журнал filteredItems, он давал мне те же неотфильтрованные элементы из контекста. Затем я выбрал Lowest, когда я консоль логировал свой filteredItems, он дал то, что я выбрал ранее, а именно Highest, и мои товары отсортированы по самой высокой цене.

Почему задержка в filteredItems? Что я сделал не так? Любая помощь будет принята с благодарностью !!

1 Ответ

1 голос
/ 12 июля 2020

Вот рабочий пример: https://codesandbox.io/s/musing-wind-4gcbf?file= / src / GlobalContext. js

Некоторые примечания:

  1. Ваш applyFilter устанавливает переменную данных для ссылки на элементы, и поскольку sort мутирует, вы изменяете состояние посредством ссылки. Вместо этого я условно отсортировал копию элементов в возвращении.
  2. Хотя индекс не используется напрямую в качестве ключа итерации, идентификаторы элементов линейны и могут повлиять на способность отслеживания реакции.
...