React中redux的使用详解

 更新时间:2023年12月20日 15:20:57   作者:lllllllllzj  
Redux 是一个状态管理库,它可以帮助你管理应用程序中的所有状态,Redux的核心概念之一是Store,它表示整个应用程序的状态,这篇文章给大家介绍React中redux的使用,感兴趣的朋友一起看看吧

1.  Redux 是什么

- Redux 是一个状态管理库,它可以帮助你管理应用程序中的所有状态(如 UI、网络请求、授权状态等)。
- Redux 采用了单向数据流的架构,意味着状态更新是通过分发 action 给 reducer 来实现的,这个 reducer 会根据 action 返回一份新的状态。
- Redux 的主要思想是“Store 保存应用的完整状态,Action 是把数据从应用(即 UI 层)传到 Store 的有效载荷,Reducer 定义了应用状态的变化如何响应 Action 并发送到 Store”。

2. Redux 的基础概念

2.1 Store:存储应用程序状态的容器。

Redux的核心概念之一是Store,它表示整个应用程序的状态。Store是一个存储JavaScript对象的容器,表示应用程序的当前状态。它可以被认为是一个大型全局变量,存储着应用程序的所有数据。

Redux Store也提供了一些有用的方法,来获取和更新应用程序的状态。例如,getState()方法可以用来检索应用程序的当前状态,而dispatch()方法可以用来调度action以更新状态。

创建一个Redux Store的基本步骤是:

1.定义一个reducer函数,用于处理各种action类型并更新应用程序状态。
2.使用该reducer函数创建一个Store,通过createStore函数完成此操作。
3.将Store与你的React组件或其他JavaScript代码连接起来,以便你的应用程序可以读取和更新状态。这可以通过在React应用程序中使用高阶组件(如connect)或原始JavaScript中的getState和dispatch方法完成。

2.2 Action:一个对象,用于描述发生的事件和相关数据(例如,用户点击按钮)。

在Redux中,Action是描述应用程序发生了什么操作的普通JavaScript对象。它代表应用程序中的一些事件,如用户交互或网络请求的结果,并且指示应用程序该如何响应这些事件。Action对象必须具有一个type属性,以指示要执行的操作类型。

例如,可以在Redux中定义如下的Action对象:

const addTodo = {
  type: 'ADD_TODO',
  payload: {
    id: 1,
    text: 'Learn Redux',
    completed: false
  }
}

在这个例子中,`addTodo`是一个Action对象,它代表要执行的操作是向列表中添加一个新的待办事项。它包含一个类型为`ADD_TODO`的type属性,以及一个payload属性,其中包含要添加的新事项的信息。

Action对象通常是由应用程序中的用户交互或一些异步事件(如HTTP响应)触发的。当Action被触发时,应用程序需要将它发送到Redux Store中,以便Store可以更新应用程序的状态并通知所有已连接的React组件。

可以通过在Redux中使用`dispatch`函数来发送Action对象。`dispatch`函数是一个Store对象的方法,它接收一个Action对象作为输入,并在Store中处理该操作。然后Store更新应用程序的状态,然后通知所有已连接的组件,以便它们可以提取更新后的状态并进行重新渲染。

2.3 Reducer:一个纯函数,接收当前状态和 action,返回新的状态。

在Redux中,Reducer是用于管理应用程序状态的纯函数。Reducer函数接收两个参数:当前状态(state)和一个Action对象,然后返回新状态。Reducer函数不会修改原始状态,而是根据Action对象生成新状态。

Reducer通常被拆分成多个小函数,每个函数负责处理应用程序状态中的特定部分。这样做可以使Reducer更加可维护和可测试,因为每个Reducer函数都只处理一小部分状态。

Redux中Reducer函数的基本结构:

function myReducer(state = initialState, action) {
  switch(action.type) {
    case 'SOME_ACTION':
      // change state and return the new state
      return newState;
    default:
      // if action type is not matched, return the current state
      return state;
  }
}

在这个例子中,`myReducer`是一个Reducer函数。它接收当前状态(`state`)和一个Action对象作为输入。如果Action的类型与`SOME_ACTION`匹配,Reducer会通过改变状态生成新状态(`newState`)并将其返回。否则,Reducer将保留当前状态并返回它。

使用Reducer可以使应用程序状态管理更加清晰和可预测。它把所有状态变更的逻辑都放在单独的函数中,这样调试和测试变得更加容易。同时,它也有助于应用程序的可扩展性和可维护性。

2.4 Dispatch:一个函数,用于分发 action。

在Redux中,Dispatch是一个Store对象的方法,用于分发(dispatch)一个Action对象以更新应用程序的状态。Dispatch方法接收一个Action对象作为输入,并且调用Store中的Reducer函数来计算新的应用程序状态。Redux Store然后存储新状态,并通知已连接的React组件以进行重新渲染。

使用Dispatch,您可以将Action对象应用于应用程序的状态(例如增加一个项目到待办事项列表)。当您调用Dispatch方法时,Redux Store会计算新状态,然后通知您的React组件。您的组件可以根据新状态重新渲染,显示新项目的列表。

在Redux中,Dispatch的基本语法如下:

store.dispatch(action)

在这个例子中,`store`是一个Redux Store对象,`action`是一个带有type属性的包含应用程序发生操作的Action对象。当调用该Dispatch方法时,Store对象将Action对象发送到Store中,Reducer函数计算出应该如何更新状态,并通知所有连接的React组件进行重新渲染。

Dispatch是Redux中非常重要的一个方法,它使得应用程序状态的改变更加可预测,可控。同时,Dispatch方法也使状态管理变得更加清晰,因为所有状态的变更都通过Action对象传递并在Reducer函数中处理。

2.5 Middleware:一个函数,可以扩展 Redux 的功能,例如在 action 到达 reducer 之前记录 action、处理异步 action、实现路由机制等。

在Redux中,Middleware是一个位于Dispatch和Reducer之间的函数,在Action到达Reducer之前拦截它们。Middleware提供一种机制,可以让您在执行Action和更新应用程序状态之间进行额外的处理。例如,中间件可以用于监视Action对象或在网络请求期间显示进度条等。

Redux中的Middleware必须是一个函数,它接收三个参数:`store`、`next`和`action`。`store`对象提供对Redux Store的访问,`next`是一个函数,它允许Action继续传递到下一个Middleware或最终到达Reducer。此外,Middleware还需要返回处理Action的函数。

在Redux中使用Middleware需要使用`applyMiddleware`方法增强Redux Store,它接收一个或多个Middleware函数作为输入。例如:

import { createStore, applyMiddleware } from 'redux';
import { myMiddleware } from './myMiddleware';
import rootReducer from './rootReducer';
const store = createStore(rootReducer, applyMiddleware(myMiddleware));

在这个例子中,我们使用`createStore`函数来创建Redux Store,并使用`applyMiddleware`方法增强它,以便它可以使用我们定义的`myMiddleware`中间件。中间件将在Action到达Reducer之前执行,可以进行各种操作,例如异步网络请求、发送日志、修改Action等。

Redux中的Middleware可以使应用程序更加灵活和可维护。它为开发人员提供了一种机制,可以在执行Action和更新状态之间执行自定义操作,以及拦截和修改Action对象。

3. 如何使用 Redux

3.1 安装 Redux 并初始化 Store

在进行Redux开发之前,您需要首先安装Redux库。您可以使用npm命令来进行安装:

npm install redux

安装完成之后,您可以开始使用Redux。

下面是一个基本的Redux Store初始化示例:

import { createStore } from 'redux';
import rootReducer from './reducers';
const store = createStore(rootReducer);

在这个例子中,我们首先导入Redux库的`createStore`函数,然后导入我们的根Reducer函数`rootReducer`。接着,我们使用`createStore`函数来创建Redux Store对象,并将`rootReducer`作为参数传递。

现在,我们已经创建了一个基本的Redux Store对象,但是它还没有与我们的React应用程序连接起来。为了将Redux Store与React应用程序连接起来,您需要使用Redux提供的一个称为`Provider`的React组件,它允许您将Redux Store作为prop传递给React组件树中的所有组件。例如:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

在这个例子中,我们使用`Provider`组件将Redux Store传递给React应用程序,并将`App`组件作为其子元素。现在,我们的Redux Store可以在整个应用程序中使用,并与React组件进行交互了。

3.2  创建 action 和 reducer

在Redux中,Action和Reducer是两个非常重要的概念,它们一起协作来管理您的应用程序状态。

在Redux中,Action必须是一个带有`type`属性的纯对象,该属性指定Action的类型。例如:

const ADD_TODO = 'ADD_TODO';
const addTodo = (text) => {
  return {
    type: ADD_TODO,
    text
  }
};

在这个例子中,`addTodo`函数是一个Action Creator,它接收带有todo文本的参数,并生成一个带有`type`属性的Action对象和一个`payload`属性。每个Action都应该有一个唯一的类型,在这种情况下是`ADD_TODO`。根据Redux约定,`payload`属性可选,用于传递有关Action的附加信息。

在Redux中,Reducer是一个纯函数,其接收应用程序的当前状态和传递的Action对象作为参数,并返回应用程序的新状态。Reducer通常分多个小函数,每个函数处理应用程序状态中的一部分。例如:

const initialState = {
  todos: []
};
function todoReducer(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [
          ...state.todos,
          { text: action.text, completed: false }
        ]
      };
    default:
      return state;
  }
}

在这个例子中,`todoReducer`是一个处理Todo列表的Reducer函数。它接收当前状态和传递的Action对象,并根据Action类型更新状态。在`ADD_TODO`类型的Action中,它在现有Todo列表中添加一个新的Todo,并返回更新后的新状态。如果Action类型不是`ADD_TODO`,则返回当前状态。

Reducer是一个纯函数,它不得修改任何传递给它的参数,也不得有任何副作用。Reducer必须始终返回一个新的状态对象,不得直接修改原始状态。

在Redux应用程序中,不断变化的状态被保存在一个称为Store的单一对象中。该Store由Redux库提供,并包括用于更新状态的`dispatch`方法。使用Action和Reducer,Redux提供了一种可预测的状态管理机制,使得管理和跟踪应用程序状态变得更加容易。

3.3 在组件中使用 mapStateToProps 和 mapDispatchToProps 函数将 Store 中的状态和 dispatch 函数映射到组件的 props 上

在Redux中,`mapStateToProps`和`mapDispatchToProps`函数用于将Redux Store中的状态和dispatch函数映射到React组件的props上。通过将这些数据和函数作为props传递给组件,您可以轻松地在组件中对应用程序状态进行操作,这也是Redux和React协作的关键之一。

`mapStateToProps`函数用于将Redux Store中的部分状态映射到组件的props上。该函数接收整个Redux Store作为参数,并返回一个对象,对象中的每个键值对都将成为组件的props。例如:

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

在这个例子中,`mapStateToProps`函数将Redux Store中名为`todos`的状态映射到组件的props上。现在,组件可以通过`this.props.todos`来访问Redux Store中的`todos`状态。

`mapDispatchToProps`函数用于将dispatch函数映射到组件的props上。该函数接收`dispatch`作为参数,并返回一个包含dispatch操作的对象。例如:

const mapDispatchToProps = (dispatch) => {
  return {
    addTodo: (text) => dispatch(addTodo(text)),
    completeTodo: (id) => dispatch(completeTodo(id))
  }
};

在这个例子中,`mapDispatchToProps`函数将`addTodo`和`completeTodo`函数映射到组件的props上,并使用`dispatch`函数分派`ADD_TODO`和`COMPLETE_TODO`操作。现在,组件可以通过`this.props.addTodo`和`this.props.completeTodo`方法来调用dispatch操作,以更新Redux Store中的应用程序状态。

一旦您定义了`mapStateToProps`和`mapDispatchToProps`函数,您可以使用`connect`方法将它们连接到React组件中,并将Redux Store作为参数传递。例如:

import { connect } from 'react-redux';
import { addTodo, completeTodo } from './actions';
import MyComponent from './MyComponent';
const mapStateToProps = (state) => {
  return { todos: state.todos }
};
const mapDispatchToProps = (dispatch) => {
  return {
    addTodo: (text) => dispatch(addTodo(text)),
    completeTodo: (id) => dispatch(completeTodo(id))
  }
};
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

在这个例子中,我们使用`connect`方法将`mapStateToProps`和`mapDispatchToProps`函数与`MyComponent`组件连接,并将`connect`方法的结果导出。现在,`MyComponent`组件可以通过`this.props.todos`, `this.props.addTodo`和`this.props.completeTodo`访问Redux Store中的数据和方法。

3.4 向 Store 分发 action

在Redux中,要分发(Dispatch)一个Action,需要使用`dispatch`方法,并向它传递需要分发的Action对象。例如:

import { useDispatch } from 'react-redux';
import { addTodo } from './actions';
const AddTodoForm = () => {
  const dispatch = useDispatch();
  const handleSubmit = (event) => {
    event.preventDefault();
    const text = event.target.elements.todo.value;
    dispatch(addTodo(text));
    event.target.reset();
  };
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="todo" />
      <button type="submit">Add Todo</button>
    </form>
  );
};

在这个例子中,我们使用`useDispatch`钩子来获取`dispatch`函数。在处理表单提交事件时,我们使用`dispatch`函数将新的`addTodo` Action分发到Redux Store中。通过这种方式,Redux Store中的状态将更新,同时也将触发组件的重新渲染,以反映新的应用程序状态。

注意,您需要将`addTodo` Action Creator作为参数传递给`dispatch`方法,而不是直接将Action对象传递给它。在Redux应用程序中,Action Creator负责创建符合Redux规范的Action对象,并将其传递给dispatch函数以进行分发。

通过分发Action对象,Redux应用程序将会响应它,调用相应的Reducer函数,更新Store中的状态,导致组件被重新渲染。每个Action Creator都应该返回一个Action对象,表示需要执行的操作。在Redux中,一个Action表示了一项任务,但并不负责执行它,而是由Reducer函数去处理。

4. 使用 React-Redux 简化 Redux

`React-Redux`是一个Redux与React协同工作的库,它提供了一些简化Redux使用的组件和方法。使用React-Redux,您可以更轻松地将Redux的状态和操作映射到您的React组件上。

`Provider` 组件是React-Redux的核心组件,它允许您将Redux Store作为prop传递给React应用程序中的所有组件,使得Redux Store可以在整个组件树中使用。例如:

import { Provider } from 'react-redux';
import store from './store';
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

在这个例子中,我们使用`Provider`组件将Redux Store作为prop传递给整个React应用程序,并将`App`组件作为`Provider`的子组件。现在,`App`组件以及它的子孙组件可以轻松地从Redux Store中读取和更新应用程序状态。

`connect()`方法是React-Redux的主要方法,它允许您将Redux的状态和操作与React组件连接起来。使用`connect()`方法,您可以轻松地将Redux Store中的状态和操作映射到组件的props上。

import { connect } from 'react-redux';
import { addTodo } from './actions';
import MyComponent from './MyComponent';
const mapStateToProps = (state) => {
  return { todos: state.todos }
};
const mapDispatchToProps = (dispatch) => {
  return {
    addTodo: (text) => dispatch(addTodo(text)),
  }
};
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

在这个例子中,我们使用`connect()`方法将`mapStateToProps`和`mapDispatchToProps`函数与`MyComponent`组件连接起来,并将连接结果导出。现在,`MyComponent`组件可以通过`this.props.todos`和`this.props.addTodo`来访问Redux Store中的状态和操作。

React-Redux还提供了两个钩子,`useSelector`和`useDispatch`,它们允许您轻松地在React组件中使用Redux的状态和操作。

import { useSelector, useDispatch } from 'react-redux';
import { addTodo } from './actions';
const AddTodoForm = () => {
  const dispatch = useDispatch();
  const todos = useSelector(state => state.todos);
  const handleSubmit = (event) => {
    event.preventDefault();
    const text = event.target.elements.todo.value;
    dispatch(addTodo(text));
    event.target.reset();
  };
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="todo" />
      <button type="submit">Add Todo</button>
    </form>
  );
};

在这个例子中,我们使用`useDispatch`钩子获取`dispatch`函数,并使用它来分发`addTodo` Action。同时,我们使用`useSelector`钩子获取Redux Store中的`todos`状态,并将其传递给组件作为一个变量。

React-Redux提供了许多其他的组件和方法来帮助您更轻松地使用Redux,并提供了简化Redux操作的体验。例如,React-Redux提供了一个`useStore`钩子,它允许您获取Redux Store对象,以便进行更高级的操作。

5. 使用 Redux 中间件

Redux中间件是一种用于拦截Redux Action并在Action到达Reducer之前执行任务的机制。使用Redux中间件,您可以在处理Action之前或之后执行额外的任务,例如调用API或记录日志。

5.1 安装和使用中间件

要使用Redux中间件,您需要使用Redux的`applyMiddleware`函数将中间件连接到Store上。例如:

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import loggerMiddleware from 'redux-logger';
import rootReducer from './reducers';
const middlewares = [thunkMiddleware, loggerMiddleware];
const store = createStore(rootReducer, applyMiddleware(...middlewares));

在这个例子中,我们使用`applyMiddleware`函数将`thunkMiddleware`和`loggerMiddleware`中间件连接到Redux Store上。现在,当我们分发Action时,这些中间件将被调用,并按照指定顺序执行。

5.2 使用Thunk中间件处理异步操作

`thunkMiddleware`是一种流行的Redux中间件,它允许您使用Redux Action Creator返回函数,而不是返回常规的Action对象。这些函数通常用于异步操作,例如API请求或延迟的UI更新。

例如,一个使用`thunkMiddleware`处理异步请求的Action Creator如下所示:

const fetchTodos = () => {
  return (dispatch) => {
    dispatch({ type: FETCH_TODOS_REQUESTED });
    return fetch('/api/todos')
      .then(response => response.json())
      .then(todos => dispatch({ type: FETCH_TODOS_SUCCESS, payload: todos }))
      .catch(error => dispatch({ type: FETCH_TODOS_ERROR, error: error.message }));
  };
};

在这个例子中,`fetchTodos`函数返回一个函数,而不是返回常规的Action对象,该函数将`dispatch`函数作为参数,并在异步请求完成后将Action对象分派到Redux Store中。当我们分派这个Action时,`thunkMiddleware`会拦截该Action,并执行这个函数,而不是直接将其发送到Reducer。当异步请求完成时,`dispatch`函数将会被调用,以将异步请求的结果发送到Redux Store中。

5.3 使用Logger中间件记录应用程序状态

`loggerMiddleware`是另一个常见的Redux中间件,它允许您记录Redux Store的每个Action以及处理这些Action所用的时间。例如:

const loggerMiddleware = store => next => action => {
  console.log(`Action: ${action.type}, State:`, store.getState());
  const result = next(action);
  console.log(`New State:`, store.getState());
  return result;
};

在这个例子中,我们定义了一个名为`loggerMiddleware`的中间件函数,它接收Redux Store作为参数,并返回一个函数,该函数接收`next`函数和Action对象作为参数。在这个函数中,我们使用`console.log`记录了Action的类型和当前Redux Store的状态。然后,我们调用`next`函数以执行下一个中间件或将Action发送到Reducer。在Action处理完成后,我们再次记录状态,并返回结果。

这个简单的`loggerMiddleware`函数可以帮助您更轻松地调试Redux应用程序,以便查看Redux Store中的状态和每个Action的执行时间。

在整个应用程序中,您可以使用多个中间件将多个任务连接到Redux Store和Action处理中。这些中间件可以通过函数组合一起使用,以便以可预测的方式对每个Action进行处理。

到此这篇关于React中redux的使用的文章就介绍到这了,更多相关React redux使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React Hooks之usePolymerAction抽象代码结构设计理念

    React Hooks之usePolymerAction抽象代码结构设计理念

    这篇文章主要为大家介绍了React Hooks之usePolymerAction抽象代码结构设计理念,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • React避免子组件无效刷新的三种解决方案

    React避免子组件无效刷新的三种解决方案

    这篇文章主要给大家介绍了React三种避免子组件无效刷新的解决方案,使用React.memo,使用React.useMemo或React.useCallback,将子组件作为children来传递这三种方案,文章通过代码介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • 解决React报错Expected `onClick` listener to be a function

    解决React报错Expected `onClick` listener to be a function

    这篇文章主要为大家介绍了React报错Expected `onClick` listener to be a function解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • React 无状态组件(Stateless Component) 与高阶组件

    React 无状态组件(Stateless Component) 与高阶组件

    这篇文章主要介绍了React 无状态组件(Stateless Component) 与高阶组件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • React应用中使用Bootstrap的方法

    React应用中使用Bootstrap的方法

    本篇文章主要介绍了React应用中使用Bootstrap的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • React 路由传参的几种实现方法

    React 路由传参的几种实现方法

    React中传参方式有很多,通过路由传参的方式也是必不可少的一种,本文主要介绍了React路由传参的几种实现方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • react跳转后路由变了页面没刷新的解决

    react跳转后路由变了页面没刷新的解决

    这篇文章主要介绍了react跳转后路由变了页面没刷新的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • React 数据获取条件竞争原理解析

    React 数据获取条件竞争原理解析

    这篇文章主要为大家介绍了React 数据获取条件竞争原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Modal.confirm是否违反了React模式分析

    Modal.confirm是否违反了React模式分析

    这篇文章主要为大家介绍了Modal.confirm是否违反了React模式分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 在react中使用vuex的示例代码

    在react中使用vuex的示例代码

    这篇文章主要介绍了在react中使用vuex的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07

最新评论