Not able to understand importance of Redux with React

Tell us what’s happening:
My code runs well. The problem I am facing here is not about the code, but its logic. I understand React quite well, and I have used it earlier in a couple of projects too. But, as you might have expected I had not used it with Redux. I am new to Redux. However, I find the challenges in FCC easy, but I have not yet understood about its usage clearly. I always feel that though Redux is being used, it is highly redundant and all the things are only being managed by React, as I was doing earlier without Redux too.

In the code below, I completed challenge successfully, but I don’t understand the importance of Redux here. I inserted console.log() to check the order of functions during execution. But I found that the console.logs in Redux are only executed in the beginning, and not with any actions, like submitting or typing message. This feels to me like Redux is completely redundant, as the state initially is always empty, and it never outputs ADD in console. So, I am not able to understand the usage and importance of Redux here, or generally anywhere. I also don’t understand the actionCreator and actionReducer used in REDUX. Also, since the action creators are just like other functions, how does Redux identify it as action creator, because it is not used or called anywhere else in the code. Please help me understand.

  **Your code so far**


// Redux:
const ADD = 'ADD';

const addMessage = (message) => {
  console.log("IN ACTION CREATOR");
  return {
    type: ADD,
    message: message
  }
};

const messageReducer = (state = [], action) => {
  console.log("IN REDUCER")
  switch (action.type) {
    case ADD:
      console.log("ADD");  //THIS STATEMENT NEVER PRINTS
      return [
        ...state,
        action.message
      ];
    default:
      console.log("DEFAULT");  //ALWAYS GOES HERE.
      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) {
    console.log("HANDLE CHANGE")
    this.setState({
      input: event.target.value
    });
  }
  submitMessage() {
    console.log("SUBMIT MESSAGE");
    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>
    );
  }
};

// React-Redux:
const mapStateToProps = (state) => {
  console.log("IN STATE TO PROPS")
  return { messages: state }
};

const mapDispatchToProps = (dispatch) => {
  console.log("IN DISPATCH TO PROPS");
  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 (
      <Provider store={store}>
      <Container/>
    </Provider>
    );
  }
};
  **Your browser information:**

User Agent is: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0.

Challenge: Connect Redux to the Messages App

Link to the challenge:

Without going into the details (which at this stage I don’t feel confident enough to summarise as I’m also learning), here’s what I’ve gathered so far about redux at a high level:

  • Redux is built with a set of robust logic and features which makes it a great choice for streamlining the state management of larger apps.
  • For smaller apps, Redux may be an overkill. And there are occasions when Redux definitely overcomplicates things.
  • Even if you want to implement your own statement management, applying the core principles on which Redux is build upon may still benefit you.


Further, Redux’ official docs provide much info on why & when to use / not use redux: Should You Use Redux? | Redux
If you have the patience to read through at least some of them, you should be able to answer your own question somewhat satisfactorily.

2 Likes

The main problem is whenever I start using Redux, I always feel it does nothing better than what React would do. This may be because I don’t understand Redux clearly enough yet. The main problems I am facing are I don’t know the basic things, like:

  • when is ActionCreator even called? If it is called when the page first loads, then it seems very redundant to me, as it has no function to do initially. Also, we don’t define when actionCreator functions should trigger, meaning that we cannot control its execution. If I am wrong, please tell me.
  • how does state change in a component even affects the store?
  • what is the role of actionReducer if the React Component itself handles all the changes in the state and knows when to trigger what changes?

It would be very greatful if you could guide me pass these basic questions, which I am feeling difficult to understand even after searching for a few online resources.
Thanks.

Hello there,

As already mentioned, Redux is nothing more than JavaScript, but does an excellent job of wrapping an app’s state logic to allow for easier access throughout an app.

An example (I am slightly proud of the streamline code): Energy-App/src at master · ShaunSHamilton/Energy-App · GitHub

It is not a large or complex app, but I found it useful to add Redux so I could import (map) any state I needed in any component without passing it down the tree.

Specifically, had I not used Redux, my main file (App.tsx) would have had to have the logic (functions) for dealing with every bit of state within redux/index.ts. It would have unnecessarily bloated App.tsx, and the other component files would have been disproportionately small.


It is called when the component is mounted, like:

// mapDispatchToProps & mapStateToProps contain an object of Action Creators - I never use this term
export default connect(mapStateToProps, mapDispatchToProps)(Component);

Taking a small bit of code as an example:

// Define Action
setName: (payload: string): ReducerPayloadType => ({
    type: ActionTypes.setName,
    payload,
  }),

// Within Component
  const verifyAndLogin = (input: string) => {
    // A bunch of logic...
    (async () => {
      try {
          // Action is dispatched
          setName("chinmaymighty");
      } catch (err) {
        console.error(err);
      }
    })();
  };

// Reducer runs, when action is dispatched
function reducer(
  state: StateType = initialState,
  action: ReducerPayloadType
): StateType {
  switch (action.type) {
    case ActionTypes.setName:
      return { ...state, name: action.payload };

What you are calling an Action Creator is just a function. So, it is defined, when the page firsts loads (depending on where the component is, and which page you are referring to). It is called, when you call it, as seen above with setName. It does sit around, as any function does in JS, waiting to be used/called.

They are triggered by the component - exactly what we want.

State change in a component does not affect the store. The idea behind Redux is:

  • map the store state to the component’s props
  • Use the props as data
  • If you want new/updated data, dispatch to store state with new data
  • Component props get updated, and component refreshes (as it does with its own state)

Pretty much what I said above. The reducer updates the store state, and the component only handles its own state - not the store state.

For the most part, you will only get a feel for Redux if you have the opportunity to use it in an app. We often say it is overkill for the Front End Libraries projects, but if you use it in them to practice, then all the better for you.

Hope this helps

2 Likes

Thank you so much. It really helped me understand some of the basic things in Redux.:heart: :slight_smile:

1 Like

Hi - I needed a refresher on Redux so I redid all of FCC’s relevant challenges. As a fellow learner, I realised where your confusion came from when I was working on the same challenge Connect Redux to the Messages App.

So, yes, the challenge has got a problem: it teaches you how to connect React and Redux, and tells you to mount the connected component, but failed to even hint that actually making React surrender statement management to Redux won’t be done until the next challenge (you likely already know this by now). That’s why if you render Presentational instead of Container to AppWrapper after connection was established, the example app still works even though the challenge can’t be passed.

So, my first (and likely no longer useful ) recommendation is that you move on to the next challenge Extract Local State into Redux (which you would already have), and I’ll still throw in my two cents to supplement @Sky020 's answers (also to enhance my own understanding :smiley: ).

Obviously you had these and the other questions when you were still confused by the withheld and somewhat misleading challenge text, but allow me to elaborate nonetheless.

An action creator is called when we want it to be called, which is similar to saying we actually do define when it’s triggered.

More specifically, an action creator is wrapped in dispatch() and made available (through mapDispatchToProps and ReactRedux.connect) to a React component as a function property of the component. the function prop can then be called by e.g. an onClick event handler function, thus creating the chain of:

user action — [trigger] → event — [call] → handler function — [call] → mapped dispatch function — [call] → action creator — [create] → action object — [dispatched to] → store/action reducer — [update] → store state


Well, as demonstrated in the challenge Extract Local State into Redux, once a state is surrendered to Redux, React no longer needs to keep it locally. Updating the surrendered state is achieved through calling the mapped dispatch function prop.

React may still keep a few local states, but the significance of such states should be strictly local. They can affect the Redux managed states, but (AFAIK and happy to be corrected) only as action payload.


At this point we would all know that, when Redux is actually managing the states, a React component is supposed to dispatch actions to the Redux store, and the action reducer would reduce the existing state and a received action into an updated state.

1 Like

Redux is the predictable state container for your javascript application, as your application grows in size ,it will help alot

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