关于 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 强大的调试工具和良好的社区支持,可以显著提升开发效率和代码质量。

相关推荐
m0_748230941 小时前
Redis 通用命令
前端·redis·bootstrap
YaHuiLiang2 小时前
一切的根本都是前端“娱乐圈化”
前端·javascript·代码规范
ObjectX前端实验室3 小时前
个人网站开发记录-引流公众号 & 谷歌分析 & 谷歌广告 & GTM
前端·程序员·开源
CL_IN3 小时前
企业数据集成:实现高效调拨出库自动化
java·前端·自动化
浪九天4 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ5 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
椰果uu5 小时前
前端八股万文总结——JS+ES6
前端·javascript·es6
微wx笑5 小时前
chrome扩展程序如何实现国际化
前端·chrome
~废弃回忆 �༄6 小时前
CSS中伪类选择器
前端·javascript·css·css中伪类选择器
CUIYD_19896 小时前
Chrome 浏览器(版本号49之后)‌解决跨域问题
前端·chrome