Reputation: 3023
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
andPRODUCT MESSAGE
.
Upvotes: 0
Views: 139
Reputation: 13702
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;
})
};
Upvotes: 1
Reputation: 425
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.
Upvotes: 0
Reputation: 51
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.
Upvotes: 0