React with Redux AND a second component! Need advice.

I have done the sample from chapter 20. All is fine. Now I want to introduce a second component ( TestComponent) which does the same like the Counter component.

index.js

ReactDOM.render(
<Provider store={store}>
<App/>
<TestComponent/>
</Provider>,
destination
);

TestComponent.js

import React, {Component} from 'react';
import { connect } from 'react-redux';

class TestComponent extends Component {

  render() {
    return (
      <div className="container">
        <button className="buttons" onClick={this.props.decreaseCount}>-</button>
        <span>Test: {this.props.countValue}</span>
        <button className="buttons" onClick={this.props.increaseCount}>+</button>
      </div>
    );
  }
}

export default connect()(TestComponent);

So the buttons are not working and the countValue is not visible. How to solve this?

You need to pass the appropriate map state/dispatch values into connect()

Great, and how can I do that? In this component there aren’t any of these values. They are declared inside App.js and I do not want to do copy & paste these functions in my TestComponent file.

function mapDispatchToProps(dispatch) {
  return {
    increaseCount: function() {
      return dispatch(increaseAction);
    },
    decreaseCount: function() {
      return dispatch(decreaseAction);
    }
  };
} 

function mapStateToProps(state) {
  return {
    countValue: state.count
  };
}

Thats basically what you need to do. But you can reduce the redundancy by defining these operations in a separate file (or files) and importing them into each place where they’re needed. And this can be simplified a little more using the object version of mapDispatchToProps.

import { increaseActionCreator, decreaseActionCreator } from './actionCreators';
import { getCount } from './selectors';

// ...

const mapDispatchToProps = {
    increaseCount: increaseActionCreator,
    decreaseCount: decreaseActionCreator
};

function mapStateToProps (state) {
    return {
        countValue: getCount(state)
    };
}

And if you don’t rename the action creator functions to something different, the object shorthand helps shorten it as well

import { increaseCount, decreaseCount } from './actionCreators';

// ...

const mapDispatchToProps = {
    increaseCount,
    decreaseCount
};

Thanks, this sounds to that what i want. So one problem, can you show me please the content of the “./actionCreators” ? I am not sure what i have to code inside this file.

Action creators are functions that return action objects - the values you have as increaseAction and decreaseAction. They’re automatically wrapped in dispatch() for you as a result of using the object syntax, so one less thing to worry about.

1 Like

Alright, the solution was quite simple. Just add “export” to mapStateToProps and mapDispatchToProps functions inside App.js . Than in any new component, you can import them with:

import {mapDispatchToProps, mapStateToProps} from "./App";

and make them usable by adding this at the end of the component file:

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TestComponent)

So these functions are defined on a centralized place and can be used on each Component.
Thanks for helping!

1 Like