FNMT8L9IN82 FNMT8L9IN82 - 1 month ago 13
React JSX Question

React/Redux - Dispatch not updating view

First small react/redux project to learn both react and redux.

The onClick event on the button element fires as I can see the value in the console (in the reducer file). However, the view is not updating.

Yes, I have looked online, and I have been stuck on this issue for a full day.

What am I doing wrong?

Thanks in advance.

PanelContainer.js file:

class PanelContainer extends React.Component {

constructor(){
super();
this.state = {
color: new Color()
}
}

render(){
return (
<div class="container">
<Row>
<Cell cols={`col-sm-12 col-md-3 col-lg-3`}>
<Panel>
<PanelBody color={this.state.color.generateColor(new Gray())}>
<Title title={this.props.follower.count} />
<p>{this.props.follower.description}</p>
<p><button class="btn btn-primary" onClick={() => this.props.getFollower()}>Update</button></p>
</PanelBody>
</Panel>
</Cell>
</Row>
</div>
);
}
}

const mapStateToProps = (state) => {
return {
follower: state.followerReducer
};
};

const mapDispatchToProps = (dispatch) => {
return {
getFollower: () => {
dispatch(getFollower());
},
changeFollower: () => {
dispatch(changeFollower());
}
}
}

export default connect(mapStateToProps, mapDispatchToProps)(PanelContainer);


FolloweReducer.js file:

export default (state = { follower: { count: 0, description: "Default description" } }, action) => {
switch(action.type){
case "GET_FOLLOWER":
state = { ...state, follower: action.payload };
console.log("GET FOLLOWER", state);
break;
case "CHANGE_FOLLOWER":
state = { ...state, follower: action.payload };
console.log("CHANGE FOLLOWER", state);
break;
default:
break;
}
return state;
};


FollowerAction.js file:

export function getFollower() {
return {
type: "GET_FOLLOWER",
payload: {
count: 20,
description: "New followers added this month"
}
}
}

export function changeFollower(){
return {
type: "CHANGE_FOLLOWER",
payload: {
count: 50,
description: "Changed Followers!!!"
}
}
}


Store.js file:

const store = createStore(combineReducers({
followerReducer: followerReducer
}));

export default store;


App.js file:

import React from "react";
import ReactDom from "react-dom";
import {Provider} from "react-redux";

import PanelContainer from "./panel/PanelContainer";
import store from "./shared/Store";

let app = document.getElementById("app");
ReactDom.render(
<Provider store={store}>
<PanelContainer />
</Provider>,
app
);

Answer

I believe the reason you don't see any updates in your rendered view is because you're wrongly mapping your state with the props you pass to the component. You state->props mapping function should be:

const mapStateToProps = (state) => {
   return {
     follower: state.followerReducer.follower
   };
};

state.followerReducer is the whole state object managed by your reducer. It's clear from this line

state = { ...state, follower: action.payload };

and from your initial state definition that you store the data you update in state.followerReducer.follower

With your mapStateToProps function you have, {this.props.follower.count} in the render method will be the whole reducer object (which is {follower: {...}}.

Comments