Я только начал изучать React 2 недели go, поэтому я все еще нахожу некоторые концепции трудными. Я перешел от создания CRA к преобразованию его в Next JS и выбрал использование контекстного API с хуками для управления состоянием. Я сейчас работаю над фильтрацией списка статей, используя раскрывающийся список. Когда я выбираю статью определенного типа, список фильтруется корректно, но когда я go возвращаюсь к раскрывающемуся списку, там присутствует только оригинальная опция вместе с текущей. Когда я нажимаю на исходную опцию, все элементы списка исчезают. Я хочу предотвратить изменение параметров в раскрывающемся списке, а также разрешить фильтрацию работать в то же время, что и другие фильтры (например, фильтр сортировки по городу и фильтр по статье).
В моем коде Я борюсь с тем, чтобы выпадающий список рынков / рынков работал правильно.
Это мой контекст. js
import React, { useState, useReducer, createContext } from "react";
import { articles } from "./data";
// Create Context Object
const StateContext = React.createContext([{}, () => {}]);
// Create a provider for components to consume and subscribe to changes
const StateProvider = (props) => {
const [state, setState] = useState({
list: articles,
market: "All",
isLoading: true,
});
return (
<StateContext.Provider value={[state, setState]}>
{props.children}
</StateContext.Provider>
);
};
export { StateContext, StateProvider };
FilterControls. js:
import React from "react";
import useFilter from "../hooks/useFilter";
const Controls = () => {
const { allEntries, market, handleChange } = useFilter();
// get all unique values
const getUnique = (items, value) => {
return [...new Set(items.map((item) => item[value]))];
};
let markets = getUnique(allEntries, "market");
// add all
markets = ["All", ...markets];
// map to jsx
markets = markets.map((item, index) => {
return (
<option value={item} key={index}>
{item}
</option>
);
});
return (
<>
<div>
<section className="filter-container">
{/* select market */}
<div className="form-group">
<label htmlFor="market">Housing Market</label>
<select
name="market"
id="market"
value={market}
className="form-control drop-down"
onChange={handleChange}
>
{markets}
</select>
</div>
{/* end of select market */}
</section>
useFilter. js:
import { useContext } from "react";
import { StateContext } from "../context";
const StateFilter = () => {
const [state, setState] = useContext(StateContext);
let allEntries = formatData(state.list);
let featuredEntries = allEntries.filter((e) => e.featured === true);
let percentageOffMax = Math.max(
...allEntries.map((item) => item.percentageOff)
);
let avgppMax = Math.max(...allEntries.map((item) => item.avgpp));
function formatData(items) {
let tempItems = items.map((e) => {
let id = e.id;
let images = e.images;
let singleEntry = { ...e, images, id };
return singleEntry;
});
return tempItems.sort((a, b) => a.avgpp - b.avgpp);
}
function sortFromHighestToLowestPrices(items) {
let tempItems = items.map((e) => {
let id = e.id;
let images = e.images;
let singleEntry = { ...e, images, id };
return singleEntry;
});
return tempItems.sort((a, b) => b.avgpp - a.avgpp);
}
let highestToLowest = sortFromHighestToLowestPrices(state.list);
// console.log(state.market);
// console.log(state);
// console.log(allEntries.filter((e) => e.market === "Homeowners"));
function handleChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = event.target.name;
console.log(value);
let ftest = allEntries.filter((e) => e.market === value);
setState((state) => ({ ...state, list: ftest, [name]: value }));
// state.filterItems();
// setState((state) =>({...state.market}))
// {
// [name]: value,
// },
// this.filterItems
// );
console.log(state);
}
// allEntries.filter((e) => e.market === value);
function filterItems() {
console.log(state.list);
let { allEntries } = state.list;
// let tempEntries = [...allEntries].sort((a, b) => b.avgpp - a.avgpp);
// if (market !== "All") {
// tempEntries = tempEntries.filter((e) => e.market === market);
// }
}
console.log(filterItems());
return {
isLoading: state.isLoading,
allEntries,
featuredEntries,
sortedEntries: allEntries,
percentageOff: percentageOffMax,
percentageOffMax,
avgppMax,
handleChange,
filterItems,
};
};
export default StateFilter;
И статьи. js, где все отображается:
import React, { useContext } from "react";
import Entry from "../components/Entry";
import Title from "../components/Title";
import { StateContext } from "../context";
import FilterControls from "../components/FilterControls";
import useFilter from "../hooks/useFilter";
const FullList = () => {
const { allEntries, showAdelphi, isLoading } = useFilter();
return (
<>
<section className="all-entries">
<Title title="Featured Entries" />
<FilterControls />
<div className="all-entries-center">
{allEntries.map((e) => (
<Entry key={e.id} entry={e} />
))}
</div>
</section>