React and Redux: Part 2
Tags: javascript, webdev, beginners, react
Published: 2022-01-05 15:24:32

* Hello again! Let's continue forward with the last of these lessons for this particular section.
* In the last post we created Redux store to handle the messages array and created an action for adding new messages. Now we need to provide React access to the Redux store and the actions it needs to dispatch updates.
* React Redux provides a small API with two key features: `Provider` and `connect`.
* Here we'll focus on `Provider`. It's a wrapper component from React Redux that wraps your React app. Which then allows us to access the Redux `store` and `dispatch` functions throughout our component tree. 
* `Provider` takes two props, the Redux store and the child components of our app.
* It will look like this.

```react
// Redux:
const ADD = 'ADD';

const addMessage = (message) => {
  return {
    type: ADD,
    message
  }
};

const messageReducer = (state = [], action) => {
  switch (action.type) {
    case ADD:
      return [
        ...state,
        action.message
      ];
    default:
      return state;
  }
};



const store = Redux.createStore(messageReducer);

// React:

class DisplayMessages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: []
    }
    this.handleChange = this.handleChange.bind(this);
    this.submitMessage = this.submitMessage.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  submitMessage() {  
    this.setState((state) => {
      const currentMessage = state.input;
      return {
        input: '',
        messages: state.messages.concat(currentMessage)
      };
    });
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input
          value={this.state.input}
          onChange={this.handleChange}/><br/>
        <button onClick={this.submitMessage}>Submit</button>
        <ul>
          {this.state.messages.map( (message, idx) => {
              return (
                 <li key={idx}>{message}</li>
              )
            })
          }
        </ul>
      </div>
    );
  }
};

const Provider = ReactRedux.Provider;

class AppWrapper extends React.Component {
  // Render the Provider below this line
  render() {
    return (
    <Provider store={store}>
    <DisplayMessages/>
    </Provider>
    )
  }

};
```
* As you can see, we rendered the `Provider` from `ReactRedux` and passed the Redux store as a prop. Then we rendered the `DisplayMessages` component as a child. Once we finished, we can see our React component rendered to the page.

* Obviously there's a lot more to learn about this but I'm just basics.


#### Map State to Props
* The `Provider` component allows you to provide `state` and `dispatch` to your React components, but you must specify exactly what state and actions you want.
* You can accomplish this by creating two functions: `mapStateToProps()` and `mapDispatchToProps()`.
* With these functions, you declare what pieces of state you want to have access to and which action creators you need to be able to dispatch.
* FreeCodeCamp wants us to create a function `mapStateToProps`. For this function it will take `state` as an argument, then return an object which maps that state to specific property names. Then create a property `messages` in the object that's being returned and set it to `state`.

```react
const state = [];

function mapStateToProps(state) {
  return {
    messages: state
  }
}
```

* The properties become available to our component via `props`. FreeCodeCamp provides us with the `store.subscribe` method to implement `mapStateToProps()` behind the scenes.


#### Map Dispatch to Props
* The `mapDispatchToProps()` function is used to provide specific action creators to your React components so they can dispatch actions against the Redux store. It also returns an object that maps dispatch actions to property names, which become component `props`. With that, each property returns a function that calls `dispatch` with an action creator and any relevant action data.
* We have access to this dispatch because it's passed in to `mapDispatchToProps()` as a parameter when you define the function, just like you passed `state` to `mapStateToProps()`
* Behind the scenes, React Redux is using Redux's `store.dispatch`
* Example, we have a `addMessage()` action creator that takes a `message` as an action payload. The object returned from `mapDispatchToProps()` for this action creator would look like this.

```react
const addMessage = (message) => {
  return {
    type: 'ADD',
    message: message
  }
};

function mapDispatchToProps(dispatch) {
  return {
    submitNewMessage: (message) => {
      dispatch(addMessage(message))
    }
  }
}
```
* The object here has a property `submitNewMessage` set to the dispatch function, which takes a parameter for the new message to add when it dispatches `addMessage()`.


####Connect Redux to React
* Now that we've written both the `mapStateToProps` and the `mapDispatchToProps` functions, you can use them to map `state` and `dispatch` to the `props` of one of our React components. 
* The `connect` method has two optional arguments, `mapStateToProps()` and `mapDispatchToProps()`. They are optional because you may have a component that only needs access to state but doesn't need to dispatch any actions, or vice versa.
* To use such method, you'll have to pass in the functions as arguments, and then call the result with our component. It will look like so:

```react
connect(mapStateToProps, mapDispatchToProps)(MyComponent)
```

* FreeCodeCamp wants us to connect the component `Presentational` to Redux with the connect method from the `ReactRedux` global object, and call it on the `Presentational` component. Assigning the result to a new `const` called `ConnectedComponent` that represents the connected component.

```react
const addMessage = (message) => {
  return {
    type: 'ADD',
    message: message
  }
};

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

const mapDispatchToProps = (dispatch) => {
  return {
    submitNewMessage: (message) => {
      dispatch(addMessage(message));
    }
  }
};

class Presentational extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <h3>This is a Presentational Component</h3>
  }
};

const connect = ReactRedux.connect;
```

* Answer:
```react
 const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(Presentational)
```
* Here the The Presentational component received a prop messages via connect and received a prop submitNewMessage via connect.


####Connect Redux to the Messages App
* With learning about how to use `connect` we can now apply what we've learned to our React Component that handles messages.
* Container components are connected to Redux. These are typically responsible for dispatching actions to the store and pass store state to child components as props.
* Here FreeCodeCamp wants us to create a new component const called `Container` that uses `connect` to connect the `Presentational` component to Redux. Then, in the `AppWrapper`, render the React Redux Provider component. Pass Provider the Redux store as a prop and render `Container` as a child. Once everything is setup, you will see the messages app rendered to the page.

```react
const mapStateToProps = (state) => {
  return { messages: state }
};

const mapDispatchToProps = (dispatch) => {
  return {
    submitNewMessage: (newMessage) => {
       dispatch(addMessage(newMessage))
    }
  }
};

const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;

// Define the Container component here:


class AppWrapper extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    // Complete the return statement:
    return (null);
  }
};
```

* Answer:

```react
const mapStateToProps = (state) => {
  return { messages: state }
};

const mapDispatchToProps = (dispatch) => {
  return {
    submitNewMessage: (newMessage) => {
       dispatch(addMessage(newMessage))
    }
  }
};

const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;

const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational)


class AppWrapper extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <Provider store={store}>
      <Container/>
      
      </Provider>
    );
  }
};
```


####Extract Local State into Redux
* Nice work! Just like me you're learning about React and Redux and all it's wonders this isn't the end though. There's still so much we have to work towards and learn more about. Please don't give up on making things happen.
* Let's recall that you wrote all the Redux code so that Redux could control the state management of your React messages app. Now that Redux is connected, you need to extract the state management out of the Presentational component and into Redux. We have Redux connected, but we are handling the state locally within the Presentational component.
* FreeCodeCamp wants us In the Presentational component, remove the `messages` property in the local state. These messages will be managed by Redux. 
* Next, modify the `submitMessage()` method so that it dispatches `submitNewMessage()` from `this.props`, and pass in the current message input from local `state` as an argument. Because you removed messages from local state, remove the messages property from the call to `this.setState()` here as well. Finally, modify the `render()` method so that it maps over the messages received from `props` rather than `state`.


```react
submitMessage() {
    this.setState((state) => ({
      input: '',
      messages: state.messages.concat(state.input)
    }));
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input
          value={this.state.input}
          onChange={this.handleChange}/><br/>
        <button onClick={this.submitMessage}>Submit</button>
        <ul>
          {this.state.messages.map( (message, idx) => {
              return (
                 <li key={idx}>{message}</li>
              )
            })
          }
        </ul>
      </div>
    );
  }
};
```
* Answer:

```react
  submitMessage() {
   this.props.submitNewMessage(this.state.input)
    this.setState({
      input: ''
    })
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input
          value={this.state.input}
          onChange={this.handleChange}/><br/>
        <button onClick={this.submitMessage}>Submit</button>
        <ul>
          {this.props.messages.map( (message, idx) => {
              return (
                 <li key={idx}>{message}</li>
              )
            })
          }
        </ul>
      </div>
    );
  }
};
```


* And that is it for the React and Redux Lesson on freeCodeCamp. Thank you so much for reading these as I go through them. Helping myself and others,

Larson, Q., 2019. Frontend Development Libraries. [online] Freecodecamp.org. Available at: https://www.freecodecamp.org/learn/front-end-development-libraries/react-and-redux

This can get complicated quickly. there's a link below if you want to experiment on your own machine, the [Create React App](https://github.com/facebook/create-react-app) comes configured and ready to go.