Redux has been a real challenge to me when I first approached it.
It is pretty confusing as the abstraction level is pretty advanced given how it is set up. I believe that a better understanding of all the components and their role would have helped me out a lot.
So please see my attempt to explain that.
Why Redux?
The official documentation explains it very clearly. Redux works around 3 principles:
- Implementing a single source of truth. The state of your whole application is stored in an object tree within a single store.
- Read-only state. The only way to change the state is to emit an action, an object describing what happened.
- Changes through pure functions only. _To specify how the state tree is transformed by actions, you write pure reducers.
Store, reducer, actions? What are those and how do they work exactly?
React-Redux:
- Role: Allow the React and Redux to communicate properly. Indeed Redux is not a React dedicated library and can work with other frameworks (Angular.js and others).
- Type: Library
- Where: It will be used at multiple places. In your compenents where you access the store through the connect() function (c.f.: below). At the higher level of your app where you will use the component (c.f.: below).
Actions:
- Role: Operations that will be done on a state with the purpose of modifying it.
- Type: Javascript Object. It's important. Actions are only Javascript #object
- Where: It can be defined pretty much anywhere. Best practices are to define them in a dedicated folder with a name relating to the reducer they will work with
reducers():
- Role: Function that will effectively change the state based on an action
- Type: Function
- Return values: The updated state following an action. ___The reducer should never return undefined. As such, the reducer should always have a default return value of the current state
- Where: Usually in a dedicated folder that will group all the reducers of the app together
combineReducer:
- Role: Allow to combine multiple reducers into one and having to pass only the combined reducer in the store. It mainly allows writing multiple reducers following the separation of concerns instead of a big messy reducer including all the actions needed for the app
- Type: Function
- Where: In the folder dedicated to the reducers
dispatch():
- Role:
- Persist the changes to the state (non-destructively)
- Re-render the DOM with a new state following an action
- Type: Function!
- Return values: None.
- Where: In the Redux library! No need to define it in your application!
Store:
- Role: Contains the state
- Type: Object that contains the state of the application and has access to 2 functions:
- The dispatch function: which dispatch changes to the state (given a specific action) and re-render the DOM
- A getState function: Which allows accessing the state
- Where: Usually at the highest possible level of your app so its entierty has access to it (index.js seems a good choice in a create-react-app)
createStore():
- Role: Will assign a store to a variable
Type: Function that will take a reducer as an argument which will be used to define the associated dispatch function (i.e.: by giving a reducer as an argument to the createStore function, it will allow your app to know to which reducer will your action be dispatched )
Where: The function is defined in the Redux library. You will, however, call it in your app to create the store. With the use of the combineReducer function, you usually call the createStore() function only once in your app.
Provider:
- Role: Wrap the main level component of your app and passes the store as a prop. The provider will alert the Redux app when a change to the state has been made and will re-render the React app
- Type: Component
- Where: The component will be used at the highest level of your app to wrap it.
connect():
- Role: Allow a component to get data from the store's internal state, send new data to the store's internal state and to re-render. The connect function returns a component that looks like the component it is tied to but with acess to the right data. Please note that if you have only one argument in your connect function you will have access to a dispatch function by default.
- Type: Function
- Where: You will use this function in each component where you need to access the store's internal state (read or write)
mapStateToProps():
- Role: Allow to specify which part of the store's state we need to provide to our component and allow to access to them through a given prop. mapStateToProps is executed for each change to the store's state
- Type: Function
- Where: This function is defined by the user in each component where we need to access the state
mapDispatchToProps():
- Role: Allow to access action creators through the component's props. mapDispatchToProps() takes the dispatch function as an argument allowing to dispatch the actions to the reducer
- Type: Function
- Where: This function is defined by the user in each component where we need to access the state
Top comments (0)