Reputation: 115
It is necessary to sort the data and then filter. When you click on a column header, sorting should occur. On the first click, it should sort in ascending order, on the second click - in descending order, and on the third click, there should be no sorting. Filtering should be performed by the text entered by the user in the field.
When you click on a column header, there is a change in redux, but the data going into the selector does not change. When a field is changed, filtering and sorting occurs.
AppContainer.js:
import {connect} from "react-redux";
import {FilterAC, PageNumberAC, RowsAC} from "./store/filter";
import {App} from "./App";
import React,{useState} from "react";
import {itemsSelector} from "./selector";
import {RowName} from "./components/RowName";
let MSTP = (state) => ({
filter: state.filter,
data: itemsSelector(state),
allItems: state.data,
pageNumber: state.pageNumber,
rows: state.rows,
sorting:state.sorting
});
let AppHOC =(props) => {
let [method,setMethod]=useState(3)
let ChangeSort = (name, method,setMethod) => {
if (method===3||props.sorting.name!==name){
setMethod(1);
method=1
}else {
setMethod(method+1);
method++
}
(method === 1)?props.RowsAC(name, "ascending"):method === 2?props.RowsAC(name, "descending"):props.RowsAC("", "");
};
let RowNames = props.rows.map((e, i) => {
return <RowName name={e} method={method} setMethod={setMethod} ChangeSort={ChangeSort} key={i}/>
})
return (
<App FilterAC={props.FilterAC} RowNames={RowNames} filter={props.filter} />
)
};
export let AppContainer = connect(MSTP, {FilterAC, PageNumberAC, RowsAC})(AppHOC);
selector.js:
import {createSelector} from "reselect";
let GetItems = (state) => {
return state.data
};
let GETFilter = (state) => {
return state.filter
};
let GETSorting = (state) => {
return state.sorting
};
export let itemsSelector = createSelector(GETFilter, GetItems, GETSorting, (filters, items, sorting) => {
let sorted = (items, sorting) => {
items = [...items];
if (sorting.name === "Name") {
items.sort((e) => {
return e.item
})
} else if (sorting.name === "Price") {
items.sort((a, b) => {
return a.price - b.price
})
} else if (sorting.name === "Number") {
items.sort((a, b) => {
return a.count - b.count
})
}
if (sorting.method === "descending") {
return items.reverse()
}
return [...items]
};
if (filters !== "") {
return sorted(items, sorting).filter((e) => {
return e.item.toLowerCase().indexOf(filters.toLowerCase()) > -1
});
} else {
return sorted(items, sorting)
}
});
RowName.js:
import React from "react";
export let RowName = (props) => {
let handler = () => {
props.ChangeSort(props.name, props.method, props.setMethod)
}
return (
<p onClick={handler}>{props.name}</p>
)
}
FindStroke.js
import React from "react";
export let FindStroke=(props)=>{
let handler=(e)=>{
props.FilterAC(e.target.value)
};
return (
<div>
<input type="text" value={props.value} onChange={handler}/>
</div>
)
}
reducer:
let data={
data:[{item:"foo",price:50,count:5},etc]
filter: "",
pageNumber: 1,
rows:['Name','Price','Number'],
sorting:{name:"",method:""}
};
export let filterReducer = (state = data, action) => {
switch (action.type) {
case "filter": {
let copyState={...state};
copyState.filter=action.filter;
copyState.pageNumber=1;
return {...copyState};
}
case "rows":{
let copyState={...state};
copyState.sorting.name=action.name;
copyState.sorting.method=action.method;
return {...copyState}
}
case "pageNumber":{
return {...state,pageNumber: action.number}
}
default :
return state
}
};
export let FilterAC = (filter) => ({
type: "filter",
filter
});
export let RowsAC = (name,method) => ({
type: "rows",
name,
method
});
export let PageNumberAC = (number) => ({
type: "pageNumber",
number
});
Upvotes: 1
Views: 106
Reputation: 115
The problem is incorrect data copying.
case "rows":{
return{...state,sorting {...state.sorting,name:action.name,method:action.method}}
}
Upvotes: 1