解析与应用官配状态管理器——Redux

前言

在当今我们 Web 项目开发中,构建绚丽又庞大的前端应用程序已经成为了常态,而伴随来就是项目渐渐复杂。在项目中,我们需要处理大量的数据流,复杂的用户交互和公共状态管理。在这个背景下,React 给我伴生出了一款强大的状态管理器------ Redux。那接下来,我就来给小伙伴们探索探索 Redux 的用法。

介绍与核心概念

首先我们知道 Redux 是一个用于JavaScript应用程序状态管理的开源库。它是帮助我们更好的组织和管理应用程序的状态,使我们在仓库定义的状态的变化可以预测和调试。

Rudex的核心概念有四点:

  1. 单一数据源 : 我们的状态都被储存在一个单一的 Store 中,每个 Store 的状态是不互通的,而且这些状态是只读的,不能直接的修改,我们只能通过发起一个描述变化的 Action 来触发状态的修改。

  2. 状态是只读的 : Redux 不允许直接修改状态,如果想要改变某个状态,我们需要创建一个描述状态变化的Reducer 纯粹函数,它可以接收当前状态和 Action 作为参数,并且返回出一个新的状态,保持了状态的不可变性,并使得状态变化可追踪和调试。

  3. 使用纯粹函数进行状态修改 : 我们创建的Reducer是一个纯粹的函数, 它根据传入的Action类型和数据来计算新的状态,它不会产生任何副作用。

  4. 通过订阅和派发实现数据流 : 在项目中,我们需要通过调用dispatch方法并传递一个 Action 来触发状态的变化。当状态发生变化时,所有订阅了Store的视图都会被通知到,并更新界面。这样就使我们的数据流变成了单向性的,使用中也就使数据变得更加的可控。

在介绍完上述四点核心概念之后,那下一步我们就在项目中将这四点核心概念给用上。

应用

首先我们来创建一个空的仓库,文件结构如下:

我们先建了一个index.js作为我们整个仓库的出口,同时又在 modules 文件夹下贱了两个独立的空仓库。

我们先来看看我们的仓库出口代码是怎么写的:

javascript 复制代码
import { configureStore } from '@reduxjs/toolkit'
import counterStore from './modules/couterStore'
import testStore from './modules/testStore'

export default configureStore({
    reducer: {
        counterStore,
        testStore
    }
})

从上述代码看出,我们使用了一个 configureStore 函数和纯粹函数来帮我们创建出了总体的Store仓库,其中configureStore函数还可以接收 middleware 等参数。

第二步,我们就来到了我们刚创建的coucouter.js 仓库中了,我们来往仓库加点东西,代码如下:

javascript 复制代码
import { createSlice } from '@reduxjs/toolkit'

const counter = createSlice({
    // 模块的名称,独一无二
    name: 'counter',
    // 初始数据
    initialState: {
        count: 1
    },
    // 定义用于修改数据源的方法
    reducers: {
        add(state) {
            state.count++
        }
    }
})

const { add } = counter.actions
const reduer = counter.reducer

export { add }
export default reduer

我们创建了一个名为counter的仓库, 我们往里面加入了名为count的状态,接着,我们还定义了改变状态的add方法,最后我们将方法和reducer对象给抛出。

第三步,我们就该在项目中应用上仓库了,我们来一段这样的代码:

javascript 复制代码
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { add } from '../../store/modules/couterStore'

export default function Counter() {
    const { count } = useSelector(state => state.counterStore) // 拿到 counterStore分仓库
    const disPatch = useDispatch()
    const clickHandler = () => {
        const action = add()
        // 告诉sotore, 我要修改的数据源
        disPatch(action)
    }
    
  return (
    <div>
        {count}
        <button onClick={clickHandler}>add count</button>
    </div>
  )
}

想要在组件中使用仓库,首先我们使用useSelector方法将该分仓库给拿出来,同时将我们需要的状态给解构出来,这样我们即可直接使用该状态。

那使用我们说完了,那接下来就该到修改了,修改我们则需要借助useDispatch方法,并将修改状态的add方法给拿。我们在组件定义了一个修改状态的clickHandler事件,在其中调用了add方法,最后调用disPatch方法,同时将add方法的返回值去派发数据流。这样我们才算完成了修改操作。

异步

经过这三步,我们就完成了仓库的应用,那最后我再来给小伙伴带来一段Redux 做异步请求数据的代码,感兴趣的小伙伴也可以去试试哦。

taskStore.js仓库代码:

javascript 复制代码
import { createSlice } from '@reduxjs/toolkit'
import axios from 'axios'
const test = createSlice({
    // 模块的名称,独一无二
    name: 'test',
    // 初始数据
    initialState: {
        channels: []
    },
    // 定义用于修改数据源的方法
    reducers: {
        setChannels(state, action){
            state.channels = action.payload
        } 
    }
})

 // 请求
  const url = ''
// 该方法不是 action 方法,它只是一个请求数据并派发给仓库的函数方法,可以定义在组件里。
  const fetchChannelList = () => { 
    return async (dispatch) =>{
        const res = await axios.get(url)
        dispatch(setChannels(res.data.data.channels))
    }
  }
const { setChannels } = test.actions
const reduer = test.reducer
export { setChannels, fetchChannelList }
export default reduer

在组件应用的组件代码:

javascript 复制代码
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { addTaskList, fetchChannelList } from '../../store/modules/testStore'
export default function Task() {
    const {channels } = useSelector(state => state.testStore)
    const disPatch = useDispatch()

    useEffect(() => {
        const action = fetchChannelList()
        // action(disPatch) //他们都是函数,所以这样也行
        disPatch(action)
    }, [disPatch])
  return (
    <div>
        <ul>
            {
               channels.map(item => (
                     <li key={item.id}>{item.name}</li>
               ))
            }
        </ul>
    </div>
  )
}

如上述两份代码,我们就实现了在异步请求与仓库的联动,感兴趣的小伙伴快去试试吧。

总结

通过使用 Redux, 我们可以更好地管理项目的状态,同时还减少了状态管理的复杂性,帮我们更好的梳理复杂又庞大的项目逻辑。所以在具有具有复杂数据流和交互中大型项目中,我们应当更加倾向于使用 Redux 做我们的状态管理工具。同时 Redux 还提供了一些辅助工具和扩展,例如中间件(Middleware)、异步操作处理、时间旅行调试,感兴趣的小伙伴们可以自己去了解一下哦。

相关推荐
吃杠碰小鸡18 分钟前
commitlint校验git提交信息
前端
虾球xz1 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇1 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒1 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员1 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐1 小时前
前端图像处理(一)
前端
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒1 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪2 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背2 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript