关于 Redux ,从基础实现到现代集成

什么是 Redux

  • Redux 是一种集中状态管理工具,常与 React 一起使用,但也可以独立运行。
  • 作用:通过集中管理应用状态,简化数据流管理和状态变更

为什么要使用 Redux

  • 解耦组件:无视组件层级关系,简化组件间通信。
  • 单向数据流:数据流清晰,易于调试和定位问题。
  • 调试工具:提供完善的调试工具,便于跟踪状态变化。

Redux 快速体验(使用基础实现的方式)

  • 需求:不和任何框架绑定,不使用任何构建工具,使用 Redux 实现计数器

  • 实现步骤

    1. 定义 reducer 函数:根据当前的操作类型返回新的状态。

      js 复制代码
       function reducer (state = { count: 0 }, action) {
         if (action.type === 'INCREMENT') {
           return { count: state.count + 1 }
         }
         if (action.type === 'DECREMENT') {
           return { count: state.count - 1 }
         }
         return state
       }
    2. 创建 store:使用 createStore 方法生成一个 store 实例

      js 复制代码
      const store = Redux.createStore(reducer)
    3. 订阅状态变化:使用 subscribe 方法订阅状态变化,更新视图。

      js 复制代码
       store.subscribe(() => {
         console.log('state变化了', store.getState())
         document.getElementById('count').innerText = store.getState().count
       })
    4. 提交 action 对象:使用 dispatch 方法提交 action 对象,触发状态变化。

      js 复制代码
       const inBtn = document.getElementById('increment')
       inBtn.addEventListener('click', () => {
         store.dispatch({
           type: 'INCREMENT'
         })
       })
      
       const dBtn = document.getElementById('decrement')
       dBtn.addEventListener('click', () => {
         store.dispatch({
           type: 'DECREMENT'
         })
       })
    5. 更新视图:初始渲染视图。

      js 复制代码
      <button id="decrement">-</button>
      <span id="count">0</span>
      <button id="increment">+</button>

Redux 管理数据流程梳理

为了职责清晰,数据流向明确, Redux 把整个数据修改的流程分成了三个核心概念,分别是:stateactionredure

  • state:存储应用状态的对象
  • action:描述状态变更的对象
  • reducer:根据 action 描述生成新状态的函数

Redux 与 React 环境准备

配套工具

  • 在 React 中使用 redux,官方要求安装俩个其它插件

    • Redux Toolkit:简化 Redux 逻辑编写的官方推荐工具。
    • react-redux:连接 Redux 和 React 组件的中间件。

配置基础环境

  • 使用 CRA 快速创建 React 项目

    js 复制代码
    npx create-react-app react-redux
  • 安装配套工具

    js 复制代码
    npm i @reduxjs/toolkit  react-redux
  • 启动项目

    js 复制代码
    npm run start

store 目录结构设计

  • 通常集中状态管理的部分都会单独创建一个单独的 store 目录
  • 应用通常会有很多个字 store 模块,所以创建一个 modules 目录,在内部编写业务分类的子 store
  • store 中的入口文件 index.js 的作用是组合 modules 中所有的子模块,并导出 store

使用 Redux与 React 实现 counterStore

创建 counterStore

  • counterStore.js 文件

    js 复制代码
    import { createSlice } from "@reduxjs/toolkit"
    
      const counterStore = createSlice({
        name:"counter",
        initialState:{
            count:0
        },
    
        reducers:{
            increatement(state){
                state.count++
            },
            decreatement(state){
                state.count--
            }
        }
    })
    
    const {increatement, decreatement}  = counterStore.actions
    const reducer = counterStore.reducer
    export {increatement, decreatement}
    export default reducer
  • store/index.js

    js 复制代码
    import { configureStore } from "@reduxjs/toolkit"
    import counterReducer from "./modules/counterStore"
    
    const store = configureStore({
        reducer:{
            counter: counterReducer
        }
    })
    
    export default store

注入 store

react-redux 负责把 Redux 和 React 连接起来,内置 Provider 组件通过 store 参数把创建好的 store 实例注入到应用中,链接正式建立

js 复制代码
import store from "./store";
import { Provider } from "react-redux";

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

React 组件使用 store 中的数据

在 React 组件中使用 store 中的数据,需要用到一个钩子函数 useSelector,它的作用是把 store 中的数据映射到组件中,使用示例:

js 复制代码
const { count } = useSelector((state) => state.counter);

React 组件修改 store 中的数据

React 组件中修改 store 中的数据需要借助另外一个 hook 函数 useDispatch,它的作用是生成提交 action 对象的 dispatch 函数

js 复制代码
import { useDispatch, useSelector } from "react-redux";
import { decreatement, increatement } from "./store/modules/counterStore";

function App() {
  const { count } = useSelector((state) => state.counter);
  const dispatch = useDispatch()

  return (
    <div className="App">
      <button onClick={() => {dispatch(decreatement())}}>-</button>
      {count}
      <button onClick={() => {dispatch(increatement())}}>+</button>
    </div>
  );
}

export default App;

Redux 与 React 提交 action 参数

在 reducers 的同步修改方法中添加 action 对象参数,在调用 actionCreater 的时候传递参数,参数会被传递到 action 对象的 payload 属性上

js 复制代码
return (
  <div className="App">
    <button onClick={() => {dispatch(decreatement())}}>-</button>
    {count}
    <button onClick={() => {dispatch(increatement())}}>+</button>
    <button onClick={() => {dispatch(addToNum(20))}}>+20</button>
  </div>
);
js 复制代码
addToNum(state, action) {
  state.count = action.payload;
},

总结

通过从基本的 Redux 实现到在 React 中的集成,逐步演示了如何创建和管理集中状态。通过定义 reducer 函数、创建 store 实例、订阅状态变化、提交 action 对象等步骤,构建了一个简单的计数器应用。同时,介绍了 Redux Toolkit 的使用和 react-redux 中间件的配置,以便更高效地管理状态。在实际项目中,结合 Redux 强大的调试工具和良好的社区支持,可以显著提升开发效率和代码质量。

相关推荐
程序员鱼皮14 分钟前
Gemini 3.0 发布!
前端·ai编程·gemini
程序员鱼皮16 分钟前
Gemini 3.0 炸裂发布!前端又死了???
前端·ai·程序员·互联网·代码
xiangxiongfly91518 分钟前
CSS svg
前端·css·svg
山依尽28 分钟前
如何将一个 React SPA 项目迁移到 Next.js 服务端渲染
前端·next.js
33 分钟前
使用 svgfmt 优化 SVG 图标
前端·svg·icon
Watermelo61733 分钟前
href 和 src 有什么区别,它们对性能有什么影响?
前端·javascript·vue.js·性能优化·html·html5·用户体验
hqk42 分钟前
鸿蒙零基础语法入门:开启你的开发之旅
android·前端·harmonyos
AAA阿giao44 分钟前
大厂面试之反转字符串:深入解析与实战演练
前端·javascript·数据结构·面试·职场和发展·编程技巧
专业抄代码选手1 小时前
告别“屎山”:用 Husky + Prettier + ESLint 打造前端项目的代码基石
前端
想进字节冲啊冲1 小时前
Vibe Coding 实战指南:从“手写代码”到“意图设计”的前端范式转移
前端·ai编程