Reputation: 438
The app has the following functionality.
orders
state.orders
state and using if
condition only shows the particular orders that should come under it.Suppose, an action happens on server-side & an order goes from "Open" to "In Progress" status.
Expected Behavior:
Now, the user swipes down and refreshes the tab component. On refresh, it should fetch the orders updated data from the server and update the redux orders
state. As soon as the orders
state updates, all tabs data should be updated automatically.
Actual Behavior:
The user swipes down and refreshes the tab component. On refresh, it fetches the orders updated data from the server and updates the redux orders
state. But after updating the state, the component view doesn't update appropriately. I mean, some part updates but some part doesn't update.
I guess, I am not updating the state properly in reducer. Following is the reducer code to GET and PUT the orders payload.
const orders = (state = {}, action)=> {
switch(action.type){
case 'GET_ORDERS':
return action.payload
case 'PUT_ORDERS':{
let newState = state;
if(action.payload != undefined){
action.payload.map(function(order, index){
if(newState[order.id] != undefined) {
newState[order.id].order_status = order.order_status;
} else {
newState[order.id] = order;
}
});
}
return Object.assign({}, state, action.payload);
}
}
}
I am maintaining the key of the order object by assinging the order id as key. It's because, due to refresh if new order come, keys should not be reassigned.
Upvotes: 0
Views: 1284
Reputation: 78850
You are mutating your orders rather than changing them into new objects. Even though your reducer state is producing new objects, if you have components tied to the order objects, they won't see these as changes. For example, if you have:
const { connect } = require('react-redux');
export function Order({ orderId, order }) {
return (
<div className="order">
<span className="order-id">{order.id}</span>
<span className="order-status">{order.order_status}</span>
</div>
);
}
const mapStateToProps = ({ orders }, { orderId }) => ({
order: orders[orderId]
});
export default connect(mapStateToProps)(Order);
...then the order
prop that's passed to your component will be identified as the same object, and your component won't update.
Try changing your reducer as follows:
const orders = (state = {}, action)=> {
switch(action.type){
case 'GET_ORDERS':
return action.payload
case 'PUT_ORDERS': {
const updates = action.payload.map((payloadOrder, index) => {
const oldOrder = state[payloadOrder.id];
const newOrder = oldOrder
? { ...oldOrder, order_status: payloadOrder.order_status }
: payloadOrder;
return {
[payloadOrder.id]: newOrder
};
});
return Object.assign({}, state, ...updates);
}
}
}
With this change, every order object in your state that has been modified is a new object.
Upvotes: 2