1

I ask myself if there is a way to initialize a React Component with props, and automatically make Redux aware of that to update its application state?

I made a Counter example :

import React from 'react';
import {createStore} from "redux"
import {Provider} from "react-redux"

import Counter from "./Counter"
import countReducer from "./ducks.js"

const store = createStore(countReducer)

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <div className="App">
          <Counter />
        </div>
      </Provider>
    );
  }
}

export default App;

Counter.js

import React from 'react';
import {connect} from "react-redux"
import {increment, decrement, reset} from "./ducks"

const Counter = ({count, decrement, increment, reset}) => (
    <div>
      <h1>Counter</h1>
      <button onClick={decrement}>-</button>
      <span style={{ margin: "0 10px" }}>{count}</span>
      <button onClick={increment}>+</button>
      <div>
        <button onClick={reset}>Reset</button>
      </div>
    </div>
  );

const mapStateToProps = ({count}) => ({
  count
})

const mapDispatchToProps = {
  decrement,
  increment,
  reset
}

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

ducks.js

// action creators
export const increment = () => ({
  type: "INC"
})

export const decrement = () => ({
  type: "DEC"
})

export const reset = () => ({
  type: "RESET"
})

// reducers
export default function countReducer(state = { count: 0 }, action) {

  switch (action.type) {
    case "INC":
      return { count: state.count + 1 }
    case "DEC":
      return { count: state.count - 1 }
    case "RESET":
      return state.defaultCount ? {
          count: state.defaultCount
        } : {
          count: 0
        }
    default:
      return state
  }
}

It works as expected : we can increment, decrement or reset on value 0.

But what if we want to reset on another value?

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <div className="App">
          <Counter defaultValue={10}/>
        </div>
      </Provider>
    );
  }
}

And another question that comes in my mind is how to manage 2 counters with different counters, while still let redux handle the whole state?

It is quite possible that I want to do something in the wrong way, so I would be grateful even if you have just best practice.

1 Answer 1

1

I ask myself if there is a way to initialize a React Component with props, and automatically make Redux aware of that to update its application state?

My solution for this specification is using the componentDidMount() lifecycle hook. We might have something like this:

componentDidMount(){
   if(this.props.defaultValue){
      this.props.initCounter(this.props.defaultValue);
   }
}
...
const mapDispatchToProps = dispatch({
   ...
   initCounter: defaultValue  => dispatch({type: 'INIT_COUNTER', payload: {defaultValue}})
   ...
})

We will need to handle this action in the reducer, the implementation is quite similar to the things that you've done.

And another question that comes in my mind is how to manage 2 counters with different counters, while still let redux handle the whole state?

Well then, our state will be an array of counter object, looks like this:

const reducer = (state = [ { id: 1, value:77 }, { id: 2, value: 88} ], action) => {
      switch (action.type):
           case 'INCREMENT':
               return state.map(c => {
                     if(action.payload.id === c.id) return {...c, value: c.value + 1};
                     return c;
               });
           case 'DECREMENT':
               return state.map(c => {
                     if(action.payload.id === c.id) return {...c, value: c.value - 1};
                     return c;
               })
           ...
           default:
               return state;
};

We use the id to specify the counter which needs to be updated.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.