goldbullet goldbullet - 3 months ago 70
React JSX Question

React-Redux connect() not updating component even when the state is changed without mutation

I have this codepen, where

store.subscribe()
works and
connect()
doesn't work. Specifically, the component doesn't get updated with the new props. I suspected state mutation as I thought that connect()'s shallow equality check might be ignoring the change. But, I'm using
Immutable.js
for the state change in the reducer, and I also did my own ref check in my subscribe method and it is even shallowly different for every update. I feel like something obvious must be missing here...

Component:

class App extends React.Component{
...
}

const mapStateToProps = state => ({
alerts: state.alerts
});

const mapDispatchToProps = dispatch => ({
onAlert: (type, autoHide, message) =>
dispatch({ type: 'SHOW_ALERT', payload: { message, type, autoHide } })
});

const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App);


Reducer:

const alertsReducer = (alerts=Immutable.List(), { type, payload }) => {
switch (type){
case 'SHOW_ALERT':
if (!payload.message || R.trim(payload.message).length === 0){
throw new Error('Message cannot be empty.');
}
return alerts.push(payload);
default:
return alerts;
}
};


Store:

const store = createStore(combineReducers({ alerts: alertsReducer }), applyMiddleware(ReduxThunk.default));


Render:

//** THIS DOESN'T WORK
// ReactDOM.render(<Provider store={store}><ConnectedApp /></Provider>, document.getElementById('main'));

//** THIS WORKS
store.subscribe(()=>{
render();
});
const render = () => {
ReactDOM.render(<App {...store.getState()} onAlert={
(type, autoHide, message) => store.dispatch({ type: 'SHOW_ALERT', payload: { message, type, autoHide } })
}/>, document.getElementById('main'));
};
render();


Is this because the top level state object still has the same reference? I tried removing
Immutable.js
and made the entire state the array with the reducer returning a new array every time. That still didn't work.

Versions:

react-redux@4.4.5
redux@3.5.2
react@15.3.1

Answer

if you open the console , there will be the error

addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded

to solve it you should choose between https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-with-addons.min.js and https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js, because React should be added to page once.

after that you need to add Provider from react-redux. Also you need to add key props in your lists.

changed pen http://codepen.io/anon/pen/dXLQLv?editors=0010

Comments