如何解决重新选择时重新渲染的问题?
how to fix the problem with rerender in reselect?
需要对数据进行排序,然后进行筛选。当您单击列 header 时,应该会进行排序。在第一次点击时,它应该按升序排序,在第二次点击时 - 按降序排列,在第三次点击时,不应该进行排序。应按用户在字段中输入的文本进行过滤。
当您点击列 header 时,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, 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>
)
}
减速器:
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}}
}
需要对数据进行排序,然后进行筛选。当您单击列 header 时,应该会进行排序。在第一次点击时,它应该按升序排序,在第二次点击时 - 按降序排列,在第三次点击时,不应该进行排序。应按用户在字段中输入的文本进行过滤。
当您点击列 header 时,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, 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>
)
}
减速器:
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}}
}