tarek hassan
tarek hassan

Reputation: 802

Redux counter basic example does not increment count

I am creating the most basic example of applying Redux with React to practice what I have been learning last two days, simple application to get counter state from store and increment it, that is it.

The code does everything right, and it does dispatch an action (it does console log the action type and value also inside reducer also), but It doesn't increment counter.

If you are experienced with Redux you can check the reducer directly, I think the problem is there.

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

import {createStore} from "redux";

var initialState = {
  count: 5
};

function reducer(state = initialState, action) {
  console.log(action)
  switch (action.type) {
    case "ADD":
      return {
        count: state.count + action.value
      };
    default:
      return state;
  }
}

var store = createStore(reducer, initialState);

class App extends React.Component {
  increment = () => {
    store.dispatch({type: "ADD", value: 1});
  };

  render() {
    return (
      <div className="App">
        <h1>Hello Counter Redux app</h1>
        <button onClick={this.increment}> click to increment number</button>
        <br />
        <br />
        <b> {store.getState().count} </b>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Upvotes: 1

Views: 1024

Answers (1)

Dacre Denny
Dacre Denny

Reputation: 30370

I would suggest a few revisions to your code - first, consider making use of react-redux to bind your store to your <App/> component.

Taking the react-redux based approach, you'll want to use the connect() method that this package provides, to connect your <App/> component to your actions and store:

const ConnectedApp = connect(
  state => {
    return {
      count: state.count
    };
  },
  dispatch => {
    return {
      increment: () => dispatch({ type: "ADD", value: 1 })
    };
  }
)(App);

Doing this exposes two additional props to your <App/> component: the count value (taken directly from store state) and the increment() function (which dispatches the action to your reducer). Notice that the connect() method returns a new version of your component <ConnectedAdd /> (which is used in the next step).

Next, you'll want to use the <Provider /> to mount your store to your app in the following way:

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <ConnectedApp />
  </Provider>,
  rootElement
);

Finally, a bit of refactoring to your <App/> component's render() method completes this process:

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <h1>Hello Counter Redux app</h1>
        <button onClick={this.props.increment}>
          {" "}
          click to increment number
        </button>
        <br />
        <br />
        <b> {this.props.count} </b>
      </div>
    );
  }
}

The react redux "stuff" can be a bit to get your head around at first but once you've worked with it a bit, it starts to make more sense - stick at it :-)

For a full working example please see this codesandbox

Upvotes: 1

Related Questions