Connect Redux to the Messages App help

Tell us what’s happening:
I passed this test somehow. But I really don’t know how it works. like why do even we use appWrapper?
what is Provider and how will it give the Container class to presentational component?

Your code so far


// Redux:
const ADD = 'ADD';

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

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

const store = Redux.createStore(messageReducer);

// React:
class Presentational 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() {
    const currentMessage = this.state.input;
    this.setState({
      input: '',
      messages: this.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>
    );
  }
};

// React-Redux:
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:
const Container = connect(mapStateToProps,mapDispatchToProps)(Presentational);

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

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/react-and-redux/connect-redux-to-the-messages-app

did you skip the lesson on Provider?

React Redux provides a small API with two key features: Provider and connect. Another challenge covers connect. The Provider is a wrapper component from React Redux that wraps your React app. This wrapper then allows you to access the Redux store and dispatch functions throughout your component tree. Provider takes two props, the Redux store and the child components of your app.

Edit: extra reading you may want to do

1 Like

yeah @hbar1st I got that part. What I really don’t understand why do we have make another class like appWrapper? couldn’t we just call it from reactDom directly like we call a react app?
thank you

You don’t need appWrapper. There is really nothing more to say.
On the other hand, having a wrapper makes moving it around easier. I don’t know how React apps are typically tested, but the wrapper may exist here for easier testing.

I think I have to use reactDom to call for appWrapper too. So basically all I am doing is calling react app that I have done before using simpler code (and handling state in react is no big deal) with no redux and now I am doing it again with redux and connecting it to react and provide the store to react and then using appwrapper to call back react again just for the sake of states. I really don’t see any use of redux.

Redux is about having a central location to manage shared states in your React app. Compare this to how React handles the passing of local states to different components. Also, imagine if the components that must communicate are far away from each other. Then it becomes very tedious and verbose to pass states as props across components. Not to mention reducing predictability of how your states are changed throughout the app life cycle. Redux helps you manage this.

Redux has nothing to do with AppWrapper. In here, note that it is not you who is rendering the app. So, having AppWrapper makes sense because the caller only needs AppWrapper rather than Provider, store, App, plus a bunch of other imports.

The appWrapper passes down some essentials objects and fuctions as props to the component to use Redux like state and dispatch objects. These are essential in working with the redux library.

What the OP is saying is that why you need AppWrapper while you can do something like this:

ReactDOM.render(
    <Provider store = {store}>
        <Container />
    </Provider>,
    target)

This is totally fine as, typically, the Redux enabled App will be your top level code. So if you can control what renders AppWrapper, then it doesn’t do anything special.

to my knowledge you don’t call anything from react Dom, reactDom is an API that we use to render JSX code to HTML Dom, concerning appWrapp it is a top level component that we are using to render the Provider from ReactRedux, and pass the Redux store as a prop…correct me if I’m wrong :thinking: