Reputation: 2910
i have redux store,which contains notifications as an array,now my problem is that my code to add new notification within existing array work fine ,that is store is updated successfully but my component which get notification as props using mapStateToProps function ,always receives an initial state of notification array,so when new notification is added to store its not received by my component, now when i convert my notification from array to a string then its get the updated value, anybody can help find out what i doing wrong? following is my code:
store.js
const initialState={
//not working when its an arrray
notifications:[],//same things work if i assign some string value like 'no notifiation'
}
function mainReducer(state=initialState,action){
return {
notifications:setNotification(state,action)
}
}
function configureStore(){
return createStore(
mainReducer,
initialState,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
);
}
const store=configureStore();
export default store;
my reducer
export function setNotification(state,action){
let notifications=state.notifications;
switch(action.type){
case SET_NOTIFICATION:
//this is not working ,means store is updated but component is not
notifications.push(action.payload);
//same will work if payload is string
//notification=action.payload;//assume payload is string
break;
}
return notifications;
}
my component
class Notification extends React.Component{
constructor(props){
super(props);
this.state={}
}
render(){
//this is not working when notification is an array
return <h1 style={{marginTop: '170px'}}>this is notification component {this.props.notifications.length}</h1>
//this is working when notification is string
// return <h1 style={{marginTop: '170px'}}>this is notification component {this.props.notifications}</h1>
}
}
function mapStateToProps(state){
let notifications=state.notifications
return {"notifications":notifications};
}
function mapDispatchToProps(dispatch){
return {};
}
export default connect(mapStateToProps,mapDispatchToProps)(Notification)
Upvotes: 2
Views: 329
Reputation: 2976
To start, the entire reducer should be rewritten as:
export function setNotification(state,action){
switch(action.type){
case SET_NOTIFICATION:
return {notifications:[...state.notifications,action.payload]}
default:
return state;
}
}
Upvotes: 0
Reputation: 10382
you are violating redux principle, you are mutating state when you should return a new one. your reducers should always return a new next state (or the same original) not a mutated one.
also when you have an array and do a push to it, though you are adding new values to it, its reference keep the same. hence it's natural to see the same initial value since redux wont go deep compare, its reference is the same so everything looks equal to redux.
your reducer should be more like:
export function setNotification(state, action){
switch(action.type){
case SET_NOTIFICATION:
// using spread is a normal approach but you could use javascript functions to create new objects and arrays
return { ...state, notifications: [...state.notifications, action.payload] }
default:
return state;
}
}
also your map state to props could be cleaner imo. I don't see often state.get() pattern (not even at docs) and you dont need to pass mapDispatchToProps
if you are not using it:
const mapStateToProps = ({ notifications }) => ({ notifications });
export default connect(mapStateToProps)(Notification)
Upvotes: 2