首页 > 其他分享 >Redux

Redux

时间:2024-03-10 10:45:06浏览次数:24  
标签:const React state action Redux store

Redux

目录


Redux 概念

Redux 是 React 最常用的集中状态管理工具,类似于 Vue 中的 Pinia(Vuex),可以独立于框架运行。
作用:通过集中管理的方式管理应用的状态。

image-20240227174903972.

为什么要使用 Redux ?

  1. 独立于组件,无视组件之间的层级关系,简化通信问题;
  2. 单项数据流清晰,易于定位 bug;
  3. 调试工具配套良好,方便调试。

1、实现计数器

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

image-20240227175003483.
使用步骤:

  1. 定义一个 reducer 函数 (根据当前想要做的修改返回一个新的状态)
  2. 使用 createStore 方法传入 reducer 函数 生成一个 store 实例对象
  3. 使用 store 实例的 subscribe 方法 订阅数据的变化(数据一旦变化,可以得到通知)
  4. 使用 store 实例的 dispatch 方法提交 action 对象 触发数据变化(告诉 reducer 你想怎么改数据)
  5. 使用 store 实例的 getState 方法 获取最新的状态数据更新到视图中

代码实现:

<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>

<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>

<script>
  // 1、定义 reducer 函数
  // 内部主要的工作是根据不同的 action 对象返回不同的新的 state
    // state:管理的数据初始状态
    // action:对象 type 标记当前
  function counterReducer (state = { count: 0 }, action) {
    switch (action.type) {
      case 'INCREMENT':
        return { count: state.count + 1 }
      case 'DECREMENT':
        return { count: state.count - 1 }
      default:
        return state
    }
  }
  // 使用reducer函数生成store实例
  const store = Redux.createStore(counterReducer)

  // 订阅数据变化
  store.subscribe(() => {
    console.log(store.getState())
    document.getElementById('count').innerText = store.getState().count

  })
  // 增
  const inBtn = document.getElementById('increment')
  inBtn.addEventListener('click', () => {
    store.dispatch({
      type: 'INCREMENT'
    })
  })
  // 减
  const dBtn = document.getElementById('decrement')
  dBtn.addEventListener('click', () => {
    store.dispatch({
      type: 'DECREMENT'
    })
  })
</script>

2、Redux 数据流架构

Redux 的难点是理解它对于数据修改的规则,下图动态展示了在整个数据的修改中,数据的流向:

image-20240227175150324.

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

  1. state:一个对象,存放着我们管理的数据
  2. action:一个对象,用来描述你想怎么改数据
  3. reducer:一个函数,根据 action 的描述生成一个新的 state


Redux 与 React — 环境准备

Redux 虽然是一个框架无关可以独立运行的插件,但是社区通常还是把它与 React 绑定在一起使用,以一个计数器案例体验一下 Redux + React 的基础使用


1、配套工具

在 React 中使用 redux,官方要求安装 2 个其他插件 — Redux Toolkitreact-redux

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

image-20240301182931016.

  1. react-redux — 用来链接 Redux 和 React 组件的中间件。

image-20240301182957832.


2、配置基础环境

npm i @reduxjs/toolkit  react-redux

3、store 目录结构设计

image-20240304144626654.

  1. 通常集中状态管理的部分都会单独创建一个单独的 store 目录

  2. 应用通常会有很多个子 store 模块,所以创建一个 modules 目录,在内部编写业务分类的子 store

  3. store 中的入口文件 index.js 的作用是组合 modules 中所有的子模块,并导出 store



Redux 与 React — 实现 counter


1、整体路径熟悉

image-20240304145310693.


2、使用 React Toolkit 创建 counterStore

image-20240305195003606.

counterStore.js

import {createSlice} from "@reduxjs/toolkit"

const counterStore = createSlice({
	name: "counter",
	// 初始状态数据
	initialState: {
		count: 0,
	},
	// 修改数据的同步方法
	reducers: {
		fn(state) {
			state.count += 1
		},
	},
})

// 解构出创建 action 对象的函数(actionCreator)
const {fn} = counterStore.actions
// 获取 reducer 函数
const counterReducer = counterStore.reducer

// 导出创建 action 对象的函数和 reducer 函数
export {fn}
export default counterReducer

store/index.js

import {configureStore} from "@reduxjs/toolkit"
import counterReducer from "./modules/counterStore.js"

// 创建根 store 组合子模块
const store = configureStore({
	reducer: {
		counter: counterReducer,
	},
})

export default store

3、为 React 注入 store

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

image-20240304230206591.

import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App.jsx"
import {Provider} from "react-redux"
import store from "./store/index.js"

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

4、React 组件使用 store 中的数据

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

image-20240305200416581.


5、React 组件修改 store 中的数据

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

image-20240305114411835.



Redux 与 React — 提交 action 传参

需求:组件中有俩个按钮 add to 10add to 20 可以直接把 count 值修改到对应的数字,目标 count 值是在组件中传递过去的,需要在提交 action 的时候传递参数。

image.png.

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

image-20240305115457053.



Redux 与 React — 异步 action 处理

需求理解
image.png.

实现步骤:

  1. 创建 store 的写法保持不变,配置好同步修改状态的方法
  2. 单独封装一个函数,在函数内部 return 一个新函数,在新函数中
    2.1 封装异步请求获取数据
    2.2 调用同步 actionCreater 传入异步数据生成一个 action 对象,并使用 dispatch 提交
  3. 组件中 dispatch 的写法保持不变

image-20240306085642506.

代码实现:

channelStore.js

import {createSlice} from "@reduxjs/toolkit"
import axios from "axios"

const channelStore = createSlice({
	name: "channel",
	initialState: {
		channelList: [],
	},
	reducers: {
		setChannelList(state, action) {
			state.channelList = action.payload
		},
	},
})
// 创建异步
const {setChannelList} = channelStore.actions
const url = "http://geek.itheima.net/v1_0/channels"

// 封装一个函数,在函数中 return 一个新函数,在新函数中封装异步
// 得到数据之后通过 dispatch 函数触发修改
const fetchChannelList = () => {
	return async (dispatch) => {
		const res = await axios.get(url)
		dispatch(setChannelList(res.data.data.channels))
	}
}

export {fetchChannelList}

const channelReducer = channelStore.reducer
export default channelReducer

App.jsx

import {useDispatch, useSelector} from "react-redux"
import {fetchChannelList} from "./store/modules/channelStore.js"
import {useEffect} from "react"

const App = () => {
	// 使用数据
	const {channelList} = useSelector(state => state.channel)
	const dispatch = useDispatch()

	useEffect(() => {
		dispatch(fetchChannelList())
	}, [dispatch])

	return (
		<>
			{channelList.map(channelItem => <li key={channelItem.id}>{channelItem.name}</li>)}
		</>
	)
}

export default App



Redux 调试 — devtools

Redux 官方提供了针对于 Redux 的调试工具,支持实时 state 信息展示,action 提交信息查看等

image-20240305120147913.

标签:const,React,state,action,Redux,store
From: https://www.cnblogs.com/rnny/p/18063810

相关文章

  • React — Redux详解
    Redux是一个用于JavaScript应用程序的状态管理库。它可以帮助您管理应用程序中的状态,并确保状态的一致性和可预测性。Redux主要用于处理大型应用程序中的复杂状态逻辑,例如跨组件共享状态、处理异步数据流等。Redux的核心概念包括:Store(存储):Redux应用程序的状态......
  • Redux函数踩坑
    redux函数踩坑Redux函数踩坑发生的问题:直接使用redux中的action发现不会直接执行返回的函数❓:action他是直接return一个函数这个函数会自己执行吗在redux中......
  • React 使用的Redux, action type 抽离成常量好还是直接写死好
    React使用的Redux,actiontype抽离成常量好还是直接写死好?在React与Redux结合进行状态管理时,将actiontype抽离成常量是一种更推荐的做法,而不是直接写死在代码中。原因如下:减少错误:如果直接在actioncreator或reducer中硬编码字符串类型的actiontype,容易因拼写错误或大......
  • Redux和@reduxjs/toolkit的使用
    1.简介:Redux是一种用于管理应用程序状态的JavaScript库。它是一个可预测的状态容器,可以用于编写可维护和可扩展的应用程序。@reduxjs/toolkit是一个官方提供的Redux工具包,它可以帮助简化Redux应用程序的开发,并提供常用的Redux原生方法,例如创建Reduxstore、定义r......
  • react-redux 的使用(三)
    react-redux的使用(三)单个组件的场景下,我们已经学会了如何从仓库里面拿值,那么其他组件怎么拿呢?关键在于store目录下的index.js文件,如下:import{createStore,applyMiddleware,combineReducers}from'redux'importthunkfrom'redux-thunk'//通过combineReducers将多......
  • react-redux 的使用(一)
    react-redux的使用(一)其实它的使用还是离不开redux它分为两部分,UI组件和容器组件(注意,原有的store文件内容不改变,并且在APP.js渲染的是容器组件)此时产生了一个大改变,就是在页面不再通过store获取数据,而是this.props.xxx容器文件代码如下:import{connect}from'react-redux'......
  • Redux的使用(一)
    Redux的使用store文件如下import{createStore}from'redux'exportconststore=createStore((preState=0,{type,data})=>{switch(type){case'add':returnpreState+datacase'jian':......
  • React 之 redux react-redux 使用
    注:官方推荐使用redux-toolkit1、项目准备创建项目npxcreate-react-app项目名称安装reduxnpminstall--saveredux安装react-reduxnpminstall--savereact-redux2、示例:Todo列表入口文件index.jsimportReactfrom"react";importReactDOMfrom"react-......
  • 记 react-redux redux-toolkit
    1、安装npminstall@reduxjs/toolkitreact-redux2、使用2.1创建一个ReduxStoreapp/store.jsimport{configureStore}from'@reduxjs/toolkit'exportconststore=configureStore({reducer:{},})2.2提供ReduxStore来Reactindex.jsimportReactfr......
  • 记Redux下载后,运行examples/todos时,报错Error: error:0308010C:digital envelope rout
    1、Redux下载下载地址gitclonehttps://github.com/reactjs/redux.git进入examples/todos,下载依赖:npminstall2、问题复现及解决执行命令npmrunstart此时终端报错:Error:error:0308010C:digitalenveloperoutines::unsupported解决方法:打开package.json,修改......