Extract Local State into Redux - extracting all the states

Tell us what’s happening:

We extracted the messages to redux. I am wondering how this code would look like if we also extracted the input state. At the end of the training, it’s not clear to me how to manage multiple states.

  **Your code so far**
```jsx
// 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:
const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;

// Change code below this line
class Presentational extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    }
    this.handleChange = this.handleChange.bind(this);
    this.submitMessage = this.submitMessage.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  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>
    );
  }
};
// Change code above this line

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

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

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

class AppWrapper extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Container/>
      </Provider>
    );
  }
};
  **Your browser information:**

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0

Challenge: Extract Local State into Redux

Link to the challenge:

Normally the store is a keyed object, making it an array is just a simplification for the tutorial.

You just have a key for each piece of state you want to track. It doesn’t really increase in complexity much, that’s why Redux is used, you can have any number of values and you deal with them all exactly the same way.

So like

const defaultState = {
  messages: [],
  inputValue: "",
}

Then, assuming your actions in this example are like {type, payload}:

function reducer (state = defaultState, action) {
  switch (action.type) {
    case "INPUT_CHANGED": {
      const newState = {...state}
      newState.inputValue = action.payload;
      return newState;
    }
    case "MESSAGE_ADDED": {
      const newState = {...state}
      newState.messages = [...newState.messages, action.payload];
      return newState;
    }
    default: {
      return state;
    }
}

Note that 99% of the time you don’t want to track the input state: it is a piece of UI that will update often. Putting it in the store will simplify things from a programming perspective. But what it will also do is cause the redux state to be recreated over and over, meaning any components that use the store will also be recreated over and over when they don’t need to be, making your app slow.

What an awesome answer Dan. Thanks for that. Yes, it makes lots of sense not saving the input state. I am still forming this mental model about what should and what shouldn’t go into the store. Thank you heaps!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.