简体   繁体   中英

How to do two type of filtering from same redux state in reactjs

I have a react js app which uses redux for state management. It has list of message which is displayed on screen. And two dropdown which filters the list according to product message and order message. Whole message list is coming from redux state.

I tried doing this but I ran into problem that once I filter the list next time it tries to run filter from filtered list and result is I get no message there.

I am not sure if this is the right way to do this.

reducers.js

const initialState = {
    loading: false,
    loaded: false,
    messageList: [],     <---- I am displaying this messageList in my component.
    fetchError: null,
}

export default (state=initialState, action) => {
    switch (action.type) {
        case GET_MESSAGE_LIST_LOAD:
            return {
                ...state,
                loading: true
            };
        case GET_MESSAGE_LIST_SUCCESS:
            return {
                ...state,
                loading: false,
                loaded: true,
                messageList: action.payload,
            };

        case FILTER_MESSAGE_BY_ORDER:
            return {
                ...state,
                filterState: action.payload,
                messageList: state.messageList.filter((item)=> {
                    return  item.productId === null;
                })
            };
        case FILTER_MESSAGE_BY_PRODUCT:
            return {
                ...state,
                filterState: action.payload,
                messageList: state.messageList.filter((item) => {
                    return item.orderNumber === null;
                })
            };
        case GET_MESSAGE_LIST_ERROR:
            return {
                ...state,
                loaded: false,
                fetchError: action.error,
            };
        default:
            return {
                ...state
            };
    }
}

action.js

export const getMessageList = () => dispatch => {
    dispatch({
        type: GET_MESSAGE_LIST_LOAD
    });
    new _rest().get('message/list')
        .then(res => {
            // console.log('messageList',res)
            dispatch({
                type: GET_MESSAGE_LIST_SUCCESS,
                payload: res.data._embedded.messageListResourceList
            })

        }).catch(err => {
            dispatch({
                type: GET_MESSAGE_LIST_ERROR,
                error: err
            })
    })
}

export const filterOrderMessage = () => dispatch => {

    dispatch({
        type: FILTER_MESSAGE_BY_ORDER
    })

}

export const filterProductMessage = () => dispatch => {

    dispatch({
        type: FILTER_MESSAGE_BY_PRODUCT
    })

}

This is how my UI Looks like It has dropdown at the top which has to options to filter ORDER MESSAGE and PRODUCT MESSAGE .

图片

You are mutating the messageList. Instead, have a separate state for filtered messages in the store. In your component, make sure to render based on filteredMessageList.

Code Sample

const initialState = {
    loading: false,
    loaded: false,
    messageList: [],
    filteredMessageList: [], // <----- create a new state
    fetchError: null,
}
...
case FILTER_MESSAGE_BY_ORDER:
            return {
                ...state,
                filterState: action.payload,
                filteredMessageList: state.messageList.filter((item)=> { // <----update filteredMessageList (not messageList)
                    return  item.productId === null;
                })
            };

Create a variable called lists, with the complete list and another one with the filtered result.

When filtering you will start the filter from the complete list, that will remains intact.

In your code, each time you dispatch an action, you changed messageList which means the next time you filter, it filter the "changed messageList" --> wrong result

My solution would be create another variable in the store, filteredList for example, each time you dispatch action filter, filteredList will change and show the result on UI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM