问题描述
需要对数据进行排序,然后进行过滤。当您单击列标题时,应进行排序。第一次点击时,应该按升序排序,第二次点击 - 降序,第三次点击时,应该没有排序。过滤应由用户在字段中输入的文本执行。
当您单击列标题时,redux 会发生变化,但进入选择器的数据不会发生变化。当一个字段发生变化时,就会发生过滤和排序。
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,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>
)
}
减速器:
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
});
解决方法
问题是数据复制不正确。
case "rows":{
return{...state,sorting {...state.sorting,name:action.name,method:action.method}}
}