Connect Redux to the Messages App

Tell us what’s happening:
stuck on challenges 4 and 5. Really hit a roadblock here can someone give me a little push? :slight_smile:

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() {
    // complete the return statement:
    return (
      <Presentational store={store}>
        {container}
      </Presentational>
    )
  }
};

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36.

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

I think you’re not too far off, here are a few things I noticed:

  • The Container constant (capital C) is actually intended to be a React Component class (hence capitalised), which is used to construct a React component using the JSX syntax (<Container />); you can only create React Components using a class that begins with a capital letter (from memory, I think, part of the reason is because lower case is reserved for regular DOM elements)

  • Following from above, container is actually a function at the moment—so passing it, which is a function, into the render method as you have now should throw an error since it’s not a React Component (that is, it’s not <Container />)

  • And I think you may have misread this of the instructions:

    in the AppWrapper, render the React Redux —Provider— component.

It should work once you will have fixed those things! Happy coding!

2 Likes

I have the same issue here:
here is my 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:
class Container extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
   const connectt = connect(mapStateToProps,mapDispatchToProps)(Presentational)
   return (
     <Presentational/>
   );
  }
}

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

I failed to connect redux to presentational component, please help me

The mapStateToProps() and mapDispatchToProps() methods map state and dispatch to the props of one of your React components. The connect method helps you do this…

connect(mapStateToProps, mapDispatchToProps)(MyComponent)

In the current exercise, we need to connect the component “Presentational” to Redux using this method. We’re also asked to assign the result of the method to a constant called “Container”

It looks like you assigned the result of the ‘connect’ method to a variable called ‘connectt.’ and you created the class ‘Container,’ which you didn’t need to do. It looks like if you just assign the result of the ‘connect’ method to the appropriate constant and get rid of the code used to define “Container” as a class, you should be alright.

1 Like

I get it now, thank you for helping me out.

1 Like