首页 > 其他分享 >Redux的基本原理以及其如何在React中使用

Redux的基本原理以及其如何在React中使用

时间:2024-11-10 18:19:38浏览次数:3  
标签:函数 基本原理 reducer React 组件 Redux store

什么是Redux?它有什么用

Redux 是一个用于 JavaScript 应用的状态管理库,通常与 React 一起使用。它帮助开发者管理应用中各个组件之间的状态,使得状态的变化变得更加可预测和易于调试。

注意:Redux也可以不和React组合使用的哦(通常一起使用)

Redux基本原理

所有的状态都以对象树的方式 (state) 存放于单个 store 中。

唯一改变状态树 (state tree) 的方法是创建 action :一个描述发生了什么的对象,并将其 dispatch 派发给 store。 要指定状态树如何响应 action 来进行更新,你可以编写纯 reducer 函数,这些函数根据旧 stateaction 来计算新 state

新的 state 被创建后,对象会自动传递给所有注册了监听器的组件,从而触发组件的重新渲染,使得界面始终保持与当前的 state 对象一致。

 

Redux在React中具体使用的方法

在React中使用redux,官方建议安装两个其他插件 - Redux Toolkit 和 React-Redux

  1. Redux Toolkit(RTK):官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式

  2. React-Redux :用来 链接 Redux 和 React 组件的中间件

  3. 安装方式

npm install @reduxjs/toolkit react-redux

下面我将详细讲解这两个插件的一些具体使用场景和常用函数。

Redux Toolkit(RTK)

非常草率的讲,就是简化Redux的使用方式推出的Toolkit(工具),这个工具中集合了方便使用Redux的一些函数。接下来我们来看一下这些函数是什么怎么用有什么用

createSlice 函数

createSlice 函数的作用是创建一个 Redux 的 slice。它接受一个包含 reducer 函数、slice 名称和初始状态的配置对象,并返回一个包含 reducer 和 action creators 的对象。

参数
  • name:slice 的名称,用于标识状态的一部分。
  • initialState:slice 的初始状态,定义了状态的初始值。
  • reducers:一个对象,包含一组同步的 reducer 函数,用于更新状态。
返回值

createSlice 返回一个包含以下属性的对象:

  • name:slice 的名称。
  • reducer:一个 reducer 函数,用于处理来自 action creators 的动作并更新状态。
  • actions:一组 action creators,用于创建派发给 reducer 的动作。
示例
import { createSlice } from '@reduxjs/toolkit';

// 定义初始状态
const initialState = {
  count: 0,
};

// 创建一个 Redux slice
const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    // 定义同步的 reducer 函数
    increment(state) {
      state.count += 1;
    },
    decrement(state) {
      state.count -= 1;
    },
    // 可以接受额外参数的 reducer 函数
    incrementByAmount(state, action) {
      state.count += action.payload;
    },
  },
});

// 导出action creators
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// 导出reducer
export default counterSlice.reducer;

在上面的示例中,我们使用 createSlice 函数创建了一个名为 counter 的 slice。它包含一个名为 count 的状态和三个同步的 reducer 函数:incrementdecrementincrementByAmount

通过increment, decrement, incrementByAmount派发动作

通过counterSlice.reducer处理动作

configureStore 函数

configureStore 函数的作用是创建一个 Redux store。它接受一个包含 reducer 函数和其他配置选项的对象,并返回一个 Redux store 实例。

参数
  • reducer:一个或多个 reducer 函数,用于处理来自 action creators 的动作并更新状态。
  • 其他配置选项:包括 middlewaredevTools 等,用于配置 store 的行为。
返回值

configureStore 返回一个 Redux store 实例,它包含以下属性和方法:

  • getState():用于获取当前的状态。
  • dispatch(action):用于派发一个动作,以触发状态的更新。
  • subscribe(listener):用于添加一个状态变化的监听器,当状态发生变化时会被调用。
  • replaceReducer(nextReducer):用于替换当前的 reducer。
示例
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers'; // 导入根 reducer

// 创建 Redux store
const store = configureStore({
  reducer: rootReducer,
  // middleware: getDefaultMiddleware => getDefaultMiddleware(), // 使用默认的中间件
  // devTools: process.env.NODE_ENV !== 'production', // 在开发环境启用 Redux DevTools
});

export default store

在上面的示例中,我们使用 configureStore 函数创建了一个 Redux store。

我们传入了一个根 reducer rootReducer,它是一个包含所有 reducer 的对象。我们还配置了默认的中间件,并在开发环境下启用了 Redux DevTools。

React-Redux

想掌握 React-Redux 你首先要把它的概念弄清楚,这很重要!

通俗来讲,React-Redux将所有组件分成两大类:UI 组件和容器组件。

  1. UI组件:负责呈现页面。(React)
  2. 容器组件:负责管理数据和业务逻辑。(Redux)

有人可能问,Redux和React-Redux的区别是什么? 答案:React-Redux 的主要作用是简化在 React 应用中使用 Redux 的过程,提供方便的方法来连接 Redux store 和 React 组件。

下面我们来说一下React-Redux中常用的组件及方法。

Provider组件

Provider是React-Redux中的一个高阶组件,它的作用是将 Redux 的 store 传递给整个 React 应用程序,使得所有的组件都能够访问到 Redux 的状态。通过Provider,我们可以在 React 应用的任何地方使用 Redux 的状态和派发动作。

使用 Provider 的主要好处是,在整个应用程序中,任何一个组件都可以通过 connect 函数或者 useSelector 钩子来访问 Redux store 中的状态,而不需要手动地将 store 传递给每一个组件。这样做的好处有:

  1. 简化代码: 不需要在每一个组件中手动传递 store,通过 Provider,store 可以在整个应用程序中自动地传递给需要的组件。
  2. 避免 prop drilling: 避免了在组件层级结构中进行多层次的 prop 传递,提高了代码的可维护性和可读性。
  3. 一致性: 所有的组件都使用相同的 Redux store,保证了应用程序中状态的一致性。
示例
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

import store from './store';
import { Provider } from 'react-redux';

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
    <Provider store={store}>
      <App />
    </Provider>
)

在上面的示例中,我们将 Redux store 通过 Provider 传递给了根组件 <App />,这样在整个应用程序中的任何地方,我们都可以使用 React-Redux 提供的 hooks 或者高阶组件来访问 Redux 的状态,以及派发 Redux 的动作。

React组件使用store中的数据

useSelector钩子函数

useSelector 是 React-Redux 提供的一个钩子函数,它用于从 Redux store 中选择部分状态。通过 useSelector,我们可以在函数组件中订阅 Redux store 中的状态,并在状态变化时重新渲染组件。

它的作用类似于 connect 方法中的 mapStateToProps,但是更加简洁和直接。(后面说)


它接受一个选择器函数作为参数,并返回选择器函数计算得到的值。当 Redux store 中的状态发生变化时,组件将会重新渲染,以显示最新的状态。

import { useSelector } from "react-redux"

function App() {
  const {count} = useSelector((state) => state.counter)
  return <div>{count}</div>
}

export default App

在上面的示例中,我们通过 useSelector 钩子函数选择了 Redux store 中的 counter 状态,并将其赋值给 counter 变量。随后,我们将这个状态显示在组件中,当 Redux store 中的 counter 状态发生变化时,组件将会重新渲染以显示最新的状态

connect组件

connect 是 React-Redux 提供的一个函数,用于连接 React 组件和 Redux store。

上面已经说过 React-Redux 的概念了,按照我的理解,connect就是 React 和 Redux 中间的-

mapStateToProps

将Redux store中的状态映射到组件的props:

const mapStateToProps = state => {
  return {
    count: state.count,
  }
}
mapDispatchToProps

将 action creators 映射到组件的 props 中的回调函数:

const mapDispatchToProps = {
  increment,
  decrement,
}
示例
import React from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from './actions';

function App({ count, increment, decrement }) {
  return (
    <div>
      <button onClick={increment}> + </button>
      <p>{count}</p>
      <button onClick={decrement}> - </button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    count: state.count,
  }
}

const mapDispatchToProps = {
  increment,
  decrement,
}

// 使用 connect 函数连接组件和 Redux store
export default connect(mapStateToProps, mapDispatchToProps)(App)

在上面的示例中,我们通过 connect 函数将 Redux store 和组件连接起来。我们使用 mapStateToProps 函数将 Redux store 中的 count 状态映射到组件的 count props 中,同时使用 mapDispatchToProps 对象将 incrementdecrement action creators 映射到组件的 incrementdecrement props 中的回调函数。

export default connect(mapStateToProps, mapDispatchToProps)(App)

可能这里会有小伙伴很迷,这里其实是将 mapStateToPropsmapDispatchToProps 中定义的逻辑分别应用到 App 组件上,并将最终生成的容器组件导出。

React组件修改store中的数据

useDispatch钩子函数

useDispatch 是 React-Redux 提供的一个钩子函数,用于在函数组件中获取 Redux store 的 dispatch 函数。通过 useDispatch,我们可以在函数组件中派发 Redux actions,从而改变 Redux store 中的状态。

示例
import { useDispatch, useSelector } from "react-redux"
// 导入actionCreater
import { inscrement, decrement } from "./store/modules/counterSlice"

function App() {
  const { count } = useSelector((state) => state.counter)
  // 使用useDispatch()函数
  const dispatch = useDispatch()
  return (
    <div>
      {/* 加 */}
      <button onClick={() => dispatch(inscrement())}> + </button>
      {count}
      {/* 减 */}
      <button onClick={() => dispatch(decrement())}> - </button>
    </div>
  )
}

export default App

在上面的示例中,我们通过 useDispatch 钩子函数获取了 Redux store 的 dispatch 函数,并将其赋值给 dispatch 变量。随后,我们可以在组件中使用 dispatch 函数来派发 Redux actions,例如在按钮的点击事件处理函数中派发 incrementdecrement actions。

Redux异步action处理

虽然 Redux 主要用于处理同步的状态更新,但有时我们需要处理异步的操作,例如从服务器获取数据或执行一些异步任务。在 Redux 中处理异步操作通常需要使用中间件来实现。

相信能看到这的朋友们不至于我长篇大论再给您说异步吧...

Redux Thunk 中间件

将Redux中的异步action处理时,我们不得不提到Redux Thunk。

它是 Redux 提供的一个中间件,它允许我们 dispatch 函数而不仅仅是普通的 action 对象。这样,我们就可以在 action creators 中返回一个函数,而不是一个普通的 action 对象。这个函数可以接受dispatchgetState作为参数,并在其中执行异步操作。

示例

 

在上面的示例中第二点我要做详细的解释(作者刚学的时候绕的非常不舒服)

错误的想法:直接调用fetchChannels()

正确的想法dispatch(fetchChannels())

原因:当你调用 dispatch(fetchChannels()) 时,Redux Thunk 中间件会拦截这个 action,并判断它是否是一个函数。如果是函数,则 Redux Thunk 会执行这个函数,并将 dispatch 方法作为参数传递给它。在这个函数中,你可以进行异步操作,比如发送网络请求。当异步操作完成后,你可以再次使用 dispatch 来派发普通的 action 对象,这样 Redux store 就能够正确地更新状态。

标签:函数,基本原理,reducer,React,组件,Redux,store
From: https://blog.csdn.net/weixin_74009702/article/details/143664125

相关文章

  • ReactPress技术揭秘
    ReactPressGithub项目地址:https://github.com/fecommunity/reactpress欢迎Star。一、引言ReactPress是一个基于React构建的开源发布平台,它不仅可以帮助用户在支持React和MySQL数据库的服务器上快速搭建自己的博客或网站,还能作为一个功能强大的内容管理系统(CMS)使用。本......
  • Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点
    基于Servlet的Web应用(ServletWeb)    特点         使用传统的ServletAPI和SpringMVC框架。         采用阻塞I/O模型,每个请求都会占用一个线程直到请求处理完毕。         适合处理同步请求-......
  • WINDOWS XP ReactOS 4.2 对象类型
    系列文章目录文章目录系列文章目录4.2对象类型OBJECT_TYPE_INITIALIZERExpInitializeTimerImplementation()ObpInsertEntryDirectory()ObInit()IopCreateObjectTypes()4.2对象类型对象是分类的,因而是有“类型(Type)”的,前面列举了许多常用的Windows对象类型。但是要列举......
  • 4.1 WINDOWS XP,ReactOS对象与对象目录----1
    系列文章目录文章目录系列文章目录4.1对象与对象目录OBJECT_HEADERObpLookupEntryDirectory()NtCreateTimer()4.1对象与对象目录“对象(Object)”这个词现在大家都已耳熟能详了,但是对象到底是什么呢?广义地说,对象就是“目标”,行为的目标,或者说行为的受体。所以,广......
  • react 组件应用
    文章目录react组件react中组件hook函数应用useMemo技术细节(useMemo钩子函数和useCallback钩子函数)小结(依赖性数组应用)react组件函数式组件实例及应用场景实例:以下是一个简单的函数式组件,用于显示一个欢迎消息。importReactfrom'react';con......
  • ReactPress 是什么?
    ReactPressGithub项目地址:https://github.com/fecommunity/reactpress欢迎Star。ReactPress是什么?ReactPress是使用React开发的开源发布平台,用户可以在支持React和MySQL数据库的服务器上架设属于自己的博客、网站。也可以把ReactPress当作一个内容管理系统(CMS)来使......
  • MECH E4320 Batch_Reactor_Ignition
    MECHE4320(Fall2024):Homework#4PleaseturninyourhomeworkbeforethedateandtimeindicatedinCourseworks.Pleaseshowandexplainyourworkclearlyandcompletelyinordertoearnfullcredit.Pleaseincludeallpartsofthehomeworkyouwantto......
  • 使用 React Native WebView 实现 App 与 Web 的通讯
    使用ReactNativeWebView实现App与Web的通讯在移动应用开发中,常常需要在应用中嵌入网页,并实现App与Web之间的通讯。ReactNative提供了一个强大的组件——react-native-webview,可以帮助我们实现这一功能。在这篇文章中,我们将介绍如何使用react-native-webview......
  • 移动Web前端高效开发实战:HTML 5 + CSS 3 + JavaScript + Webpack + React Native + Vu
    书:pan.baidu.com/s/1tIHXj9HmIYojAHqje09DTA?pwd=jqsoHTML5新特性与应用:介绍HTML5的新特性,包括语义化标签、本地存储、设备兼容、连接特性等,并讲解如何在移动Web前端开发中充分利用这些特性提升用户体验。CSS3样式与动画设计:详细讲解CSS3的样式设计和动画效果,包括选择器、盒......
  • React-Router-Dom6 最佳实践
    React-Router-Dom6最佳实践一咻世界都变了​关注 6人赞同了该文章​展开目录 react-router-dom6使用之前只使用过一次react-router,目前官方从5开始就已经放弃了原有的react-router库,统一命名为 react-router-dom了实现......