Git Product home page Git Product logo

map-dispatch-to-props-readme-web-010818's Introduction

Introduction

So as you remember, mapStateToProps() gives us a degree of separation of concerns by allowing us to not reference our store in our component when retrieving the state. So it moved us towards having our state management in one part of our code, and our display of our state management in a different part. In other words, it started the process of removing knowledge of Redux inside our components.

What prevented us from fully removing a reference to Redux inside our components was that we did not know how to dispatch actions without calling store.dispatch() from our component. Well, in this lesson we'll learn how to do just that. We'll remove knowledge of the store from our components by using a function similar to mapStateToProps(), which is called mapDispatchToProps().

Identifying the Problem

So we're back to using the same codebase as we used in our mapStateToProps() readme. Essentially, inside the ./src/App.js file, you can see that clicking on a button dispatches an action to the store. In the mapStateToProps() readme, we changed our code such that we no longer reference the store to get an updated state of the items, but we still do reference the store to dispatch the action. If you look at the line inside the handleOnClick function, you'll see the culprit:

// ./src/app.js
...

handleOnClick(){
  this.props.store.dispatch(addItem())
}

...

Ok, so this may seem small, but it introduces our old problem. Our component is no longer indifferent about its state management system. Instead, this line of code makes the component reliant on Redux.

Well we can fix this problem with our connect() function. Just like we can write code like connect(mapStateToProps)(App) to add new props to our App component, we can pass connect() a second argument, and add our action creator as props. Then we can reference this action creator as a prop to call it from our component. We'll spend the rest of this lesson unpacking the previous sentence. Ok, let's see how this works.

Using mapDispatchToProps

We use mapDispatchToProps() by passing our connect() function a second argument that adds new props to the function, that point to action creators. So updating our ./src/App.js file, it looks like the following:

// ./src/App.js

import React, { Component } from 'react';
import './App.css';
import { connect } from 'react-redux';
import { addItem } from  './actions/items';

class App extends Component {

  handleOnClick() {
    this.props.store.dispatch(addItem());
  }

  render() {
    return (
      <div className="App">
        <button onClick={(event) => this.handleOnClick(event)}>
          Click
          </button>
        <p>{this.props.items.length}</p>
      </div>
    );
  }
};

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

/* code change */
const mapDispatchToProps = () => {
  return {
    addItem: addItem
  };
};

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

Ok, so let's see what adding our mapDispatchToProps() function, and passing it through as a second argument accomplished. We'll place in another debugger in our component, right below the word render. Now, boot up the app, open up your console and when you hit the debugger statement, type in this.props.addItem. You'll see that it returns the action creator addItem. So just like with mapStateToProps() we added a prop that pointed to a value, here we add a prop addItem that points to the value, which in this case is our action creator. So now we can change our code such that when the handleOnClick() function gets called, we execute our action creator by referencing it as a prop. Here's the code:

// ./src/App.js

...

handleOnClick() {
  this.props.addItem();
}

...

So this code calls the handleOnClick() function after the button is clicked. The handleOnClick() references and then executes the addItem() function by calling this.props.addItem(). This code does call our action creator, but it's not good enough. Remember that action creator is just a simple JavaScript function and all it returns is return a plain old JavaScript object. So right now each time we click a button, we call our action creator. What we really want to do is call our action creator, and then dispatch the returned action to the store. Well by changing our mapDispatchToProps() function a little so we can do just that.

BindActionCreators

So we know that it's not good enough to pass through a prop that we can use to execute an action creator. What we need is the ability to execute the store's dispatch function and pass the dispatch function the return value of the action creator. By accessing a function from the Redux library called bindActionCreators() we can do just that.

// ./src/App.js
import React, { Component } from 'react';
import './App.css';
import { bindActionCreators } from 'redux'; /* code change */
import { connect } from 'react-redux';

...

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

const mapDispatchToProps = (dispatch) => {
  /* code change */
  return bindActionCreators({
    addItem: addItem
  }, dispatch);
};

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

The first change we made was to add an argument to our mapDispatchToProps() function called dispatch. So just as the mapStateToProps() function receives the state from the store as its argument, the mapDispatchToProps() receives the dispatch function from the store. Now that we have this dispatch function, we have to say what we would like to eventually dispatch. We do this by using our bindActionCreators() function from Redux, and passing to it, our new props, as well as the store's dispatch function.

Now let's place back in our debugger inside the App component's render function. If you refresh the page, and now type in this.props.addItem, you will seeing the following returned:

function () {
  return dispatch(actionCreator.apply(undefined, arguments));
}

So you can see that our addItem() prop no longer directly points to the action creator, but instead points to the dispatch function, and passes through the return value of the action creator as its argument. It's ok if you don't totally understand the code above, just know that this is what it's doing. Well see it for yourself, remove the debugger, and click the button. You will see that now our view is changing as our action to 'GET_COUNT_OF_ITEMS' is being dispatched. And if you look at the Redux Devtools, you can see the action dispatched along with the corresponding state change.

Summary

In this lesson we saw that we can remove all reference to our store from our component via the mapDispatchToProps() function. We saw that mapDispatchToProps() allows us to pass through our action creator as a prop, and that by using Redux's bindActionCreators() function, we can wrap the action creator in our store's dispatch function, so that the action is properly dispatched to the store.

map-dispatch-to-props-readme-web-010818's People

Contributors

lukeghenco avatar jeffkatzy avatar cernanb avatar

Watchers

 avatar Rishikesh Tirumala avatar James Cloos avatar  avatar Victoria Thevenot avatar  avatar Joe Cardarelli avatar Katie Burke avatar Sara Tibbetts avatar The Learn Team avatar Sophie DeBenedetto avatar  avatar Antoin avatar Alex Griffith avatar  avatar Amanda D'Avria avatar  avatar Nicole Kroese  avatar Lisa Jiang avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.