SoFunction
Updated on 2025-03-02

react-redux using Redux in React project

background

In the previous articleUnderstand Redux and its working principles in one articleIn the middle, we learnedreduxis used for data state management, andreactIt is a view-level library

If you connect the two together, you can use the official recommendationreact-reduxlibrary, which has efficient and flexible features

react-reduxDivide the components into:

  • Container Components:Existing logical processing
  • UI Components:Only responsible for the current display and interaction, the internal logic is not processed, and the state is controlled by the outside.

passreduxStore the entire application state tostoreThe component can be distributeddispatchBehavioractionGivestore

Other components via subscriptionstoreStatus instateUpdate your own view

UI Components

React-Redux divides all components into two categories: UI components (presentational components) and container components.

UI components have the following characteristics:

  • Only responsible for the presentation of the UI without any business logic
  • No state (i.e. no use of this variable)
  • All data is provided by parameter()
  • Don't use any Redux API

Here is an example of a UI component:

const Title =

  value => <h1>{value}</h1>;

Because it does not contain state, a UI component is also called a "pure component", that is, it is purely a function, and its value is purely determined by parameters.

Container Components

The characteristics of container components are exactly the opposite.

  • Responsible for managing data and business logic, not responsible for presentation of UI
  • With internal state
  • Using Redux's API

In short, just remember one sentence: the UI component is responsible for the rendering of the UI, and the container component is responsible for managing data and logic.

You might ask, what if a component has both UI and business logic? The answer is, split it into the following structure: the outside is a container component, which contains a UI component. The former is responsible for communication with the outside, passing data to the latter, and rendering the view.

React-Redux stipulates that all UI components are provided by the user, and container components are automatically generated by React-Redux. In other words, the user is responsible for the visual layer, and state management is all handed over to it.

connect()

React-Redux provides a connect method to generate container components from UI components. Connect means connecting these two components.

In the above code, TodoList is a UI component, and VisibleTodoList is a container component automatically generated by React-Redux through the connect method.

However, because there is no business logic defined, the above container component is meaningless, it is just a simple wrapper layer of the UI component. In order to define business logic, the following two aspects need to be given.

  • Input logic:How to convert external data (i.e. state objects) into parameters of UI components
  • Output logic:How does the actions issued by the user become an Action object and pass out from the UI component.
import { connect } from 'react-redux'
const VisibleTodoList = connect(

  mapStateToProps,

  mapDispatchToProps

)(TodoList)

In the above code, the connect method accepts two parameters: mapStateToProps and mapDispatchToProps. They define the business logic of UI components. The former is responsible for input logic, that is, mapping state to parameters (props) of UI components, and the latter is responsible for output logic, that is, mapping user's operations on UI components into Action.

mapStateToProps()

mapStateToProps is a function. Its function is to establish a mapping relationship from (external) state object to (UI component's) props object, like its name.

As a function, mapStateToProps should return an object after execution, and each key-value pair inside is a map. Please see the example below.

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(, )

  }
}

In the above code, mapStateToProps is a function that accepts state as a parameter and returns an object. This object has a todos attribute, representing the parameter of the same name of the UI component. The subsequent getVisibleTodos is also a function, and the value of todos can be calculated from state.

The following is an example of getVisibleTodos, used to calculate todos.

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return (t => )
    case 'SHOW_ACTIVE':
      return (t => !)
    default:
      throw new Error('Unknown filter: ' + filter)
  }
}

mapStateToProps will subscribe to the Store. Whenever the state is updated, it will automatically execute and recalculate the parameters of the UI component, thereby triggering the re-rendering of the UI component.

The first parameter of mapStateToProps is always the state object, and the second parameter can also be used to represent the props object of the container component.

// Container component code//    &lt;FilterLink filter="SHOW_ALL"&gt;
//      All
//    &lt;/FilterLink&gt;

const mapStateToProps = (state, ownProps) =&gt; {

  return {
    active:  === 

  }
}

After using ownProps as a parameter, if the parameters of the container component change, it will also cause re-rendering of the UI component.

The connect method can omit the mapStateToProps parameter, so that the UI component will not subscribe to the Store, which means that the update of the Store will not cause the update of the UI component.

mapDispatchToProps()

mapDispatchToProps is the second parameter of the connect function, which is used to establish a mapping of parameters to methods of UI components. That is, it defines which users' actions should be passed to the Store as Action. It can be a function or an object.

If mapDispatchToProps is a function, you will get two parameters: dispatch and ownProps (the props object of the container component).

const mapDispatchToProps = (
  dispatch,
  ownProps
) => {
  return {
    onClick: () => {
      dispatch({
        type: 'SET_VISIBILITY_FILTER',

        filter: 

      });

    }

  };
}

From the above code, we can see that mapDispatchToProps, as a function, should return an object. Each key-value pair of the object is a map, which defines how the parameters of the UI component emit an Action.

If mapDispatchToProps is an object, each key name of it is also the same parameter of the corresponding UI component. The key value should be a function and will be regarded as an Action creator. The returned Action will be automatically issued by Redux. For example, the above mapDispatchToProps is written as an object like this.

const mapDispatchToProps = {
  onClick: (filter) => {
    type: 'SET_VISIBILITY_FILTER',
    filter: filter
  };
}

Components

After the connect method generates the container component, the container component needs to get the state object to generate the parameters of the UI component.

One solution is to pass the state object as a parameter into the container component. However, this is more troublesome, especially since the container components may be at a very deep level, it is very troublesome to pass on the state one by one.

React-Redux provides a Provider component that allows container components to get state.

import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'

let store = createStore(todoApp);
render(
  <Provider store={store}>
    <App />
  </Provider>,
  ('root')
)

In the above code, Provider covers a layer outside the root component, so that all subcomponents of the App can get state by default.

Its principle is the context property of the React component. Please see the source code:

class Provider extends Component {
  getChildContext() {
    return {
      store: 

    };

  }
  render() {
    return ;

  }
}
 = {
  store: 

}

In the above code, the store is placed on the context object context. Then, the child component can get the store from the context, and the code is roughly as follows.

class VisibleTodoList extends Component {
  componentDidMount() {
    const { store } = ;
     = (() =>
      ()
    );
  }
  render() {
    const props = ;
    const { store } = ;
    const state = ();

    // ...

  }

}
 = {
  store: 

}

React-Redux automatically generates the code of the container component, similar to the above, so as to get the store. \

Example: Counter

Let's look at an example. Below is a counter component, which is a pure UI component.

class Counter extends Component {
  render() {
    const { value, onIncreaseClick } = 
    return (
      <div>
        <span>{value}</span>

        <button onClick={onIncreaseClick}>Increase</button>
      </div>
    )
  }
}

In the above code, this UI component has two parameters: value and onIncreaseClick. The former needs to be calculated from the state, while the latter needs to issue an Action outward.

Next, define the value to state mapping, and the onIncreaseClick to dispatch mapping.

function mapStateToProps(state) {
  return {
    value: 
  }
}
function mapDispatchToProps(dispatch) {
  return {
    onIncreaseClick: () => dispatch(increaseAction)

  }

}
// Action Creator
const increaseAction = { type: 'increase' }

Then, use the connect method to generate the container component.

const App = connect(

  mapStateToProps,

  mapDispatchToProps

)(Counter)

Then, define the reducer for this component.

// Reducer
function counter(state = { count: 0 }, action) {
  const count = 
  switch () {
    case 'increase':
      return { count: count + 1 }
    default:
      return state
  }
}

Finally, generate the store object and use Provider to wrap a layer outside the root component. \

import { loadState, saveState } from './localStorage';
const persistedState = loadState();
const store = createStore(
  todoApp,
  persistedState

);
(throttle(() => {
  saveState({
    todos: ().todos,

  })
}, 1000))
(
  <Provider store={store}>
    <App />
  </Provider>,
  ('root')
);

This is all about this article about react-redux using Redux in React project. For more related content related to React using react-redux, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!