RAVI MONE RAVI MONE - 11 days ago 7
React JSX Question

Simple Redux Counter Component implementation

I am trying to implement a counter component using simple Redux , have created the

store
using
createStore
and used
store.dispatch


complete code :



/*==================================================
This is only to format the code, I have used this editor,
you can scroll down for the fiddle having error.
==================================================*/


const createStore = Redux.createStore;

const counter = (state = {
counter: 0
}, action) => {
console.log('counter', state)
switch (action.type) {
case 'INCREMENT':
return state.counter + 1;
case 'DECREMENT':
return state.counter - 1;
default:
return state;
}
}

const store = createStore(counter);

let Counter = React.createClass({
getInitialState() {
return store.getState()
},

incrementCounter() {
store.dispatch({
type: 'INCREMENT'
});
},
decrementCounter() {
store.dispatch({
type: 'DECREMENT'
});
},

render() {

console.log('NEW STATE:', store.getState(), this.state)
return (
<div>
<p>{this.state.counter}</p>
<div>
<button onClick={this.incrementCounter}>+</button>
<button onClick={this.decrementCounter}>-</button>
</div>
</div>
)
}

})

ReactDOM.render( < Counter / > , document.getElementById('container'))






DEMO JSFIDDLE

MY issue : I am not able to get the updated store value in the render block when I click on
incrementCounter
and
decrementCounter
functions

Note: Please bare with me, as I am new to redux.

Answer

You have several issues

  1. You need subscribe for state changes, it is important, because your component does not know about new state
  2. state is Object, you have to return from counter Object, in your example you return Number in INCREMENT and DECREMENT

const createStore = Redux.createStore;

const counter = (state = {
  counter: 0
}, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return Object.assign({}, state, { counter: state.counter + 1 });
    case 'DECREMENT':
      return Object.assign({}, state, { counter: state.counter - 1 });
    default:
      return state;
  }
}

const store = createStore(counter);

let Counter = React.createClass({
  incrementCounter() {
    store.dispatch({ type: 'INCREMENT' });
  },
  
  decrementCounter() {
    store.dispatch({ type: 'DECREMENT' });
  },

  render() {
    return <div>
      <p>{ this.props.value }</p>
      <div>
        <button onClick={this.incrementCounter}>+</button>
       	<button onClick={this.decrementCounter}>-</button>
      </div>
    </div> 
  }
})

const render = () => {
  ReactDOM.render(
    // get updated state value, and pass it to component
    <Counter value={ store.getState().counter } />, 
    document.getElementById('container')
  )
};

store.subscribe(render);
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

Note: for React, Redux (react-redux) provides component called Provider, and you don't need use store.subscribe, however under the hood logic similar as in my example

Comments