如何解决重新选择中重新渲染的问题?

问题描述

需要对数据进行排序,然后进行过滤。当您单击列标题时,应进行排序。第一次点击时,应该按升序排序,第二次点击 - 降序,第三次点击时,应该没有排序。过滤应由用户在字段中输入的文本执行。

当您单击列标题时,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}}
    }