react 状态管理

Redux

ReduxReact中常用的状态管理组件,类似于Vue中的Pinia(Vuex),可以独立于框架运行

作用: 通过集中管理的方式管理应用的状态

配套工具

react中使用redux,官方要求按照两个插件,Redux Toolkitreact-redux

Redux Toolkit 是官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式

react-redux 用来连接reduxreact组件的中间件

java 复制代码
npm i @reduxjs/toolkit react-redux

store目录结构设计

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

使用

counterStore.js

java 复制代码
import { createSlice } from "@reduxjs/toolkit";

const counterStore = createSlice({
    // 名称
    name: "counter",
    // 初始化状态
    initialState:{
        count:0
    },
    //修改数据的同步方法
    reducers:{
        add(store){
            store.count++
        },
        sub(store){
            store.count--
        }
    }
})
// 结构出action对象中的函数
const {add,sub} = counterStore.actions
// reducer函数
const currentReducer = counterStore.reducer
// 导出
export default currentReducer
export {add,sub}

index.js

java 复制代码
import { configureStore } from "@reduxjs/toolkit";

import counterReducer from "./modules/counterStore";

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

export default store;

为react注入store
react-redux负责把ReduxReact连接起来,内置Provider组件,通过store参数把创建好的store实例注入到应用中。

main.jsx 项目的入口文件

java 复制代码
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import store from './store'
import { Provider } from 'react-redux'

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

在组件中使用

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

java 复制代码
function App() {

  const counterReducer = useSelector(state => state.counter);

  return (
    <div>
      <div>当前值:{counterReducer.count}</div>
    </div>
  );
}



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

java 复制代码
import './App.css'
import { useSelector,useDispatch } from 'react-redux';

// 导入创建的action对象的方法
import { add, sub } from './store/modules/counterStore';
function App() {

  const counterReducer = useSelector(state => state.counter);
  // 获取dispatch函数
  const dispatch = useDispatch();

  return (
    <div>
      <div>当前值:{counterReducer.count}</div>
      {/* 调用 */}
      <button onClick={() => dispatch(add())}>加一</button>
      <button onClick={() => dispatch(sub())}>减一</button>
    </div>
  );
}

提交action传参

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

java 复制代码
import { createSlice } from "@reduxjs/toolkit";

const counterStore = createSlice({
    // 名称
    name: "counter",
    // 初始化状态
    initialState:{
        count:0
    },
    //修改数据的同步方法
    reducers:{
        add(store){
            store.count++
        },
        sub(store){
            store.count--
        },
        addNum(store,action){
            store.count+= action.payload
        }
    }
})
// 结构出action对象中的函数
const {add,sub,addNum} = counterStore.actions
// reducer函数
const currentReducer = counterStore.reducer
// 导出
export default currentReducer
export {add,sub,addNum}
java 复制代码
在这里插入代码片
import './App.css'
import { useSelector,useDispatch } from 'react-redux';

// 导入创建的action对象的方法
import { add, sub,addNum } from './store/modules/counterStore';
function App() {

  const counterReducer = useSelector(state => state.counter);
  // 获取dispatch函数
  const dispatch = useDispatch();

  return (
    <div>
      <div>当前值:{counterReducer.count}</div>
      {/* 调用 */}
      <button onClick={() => dispatch(add())}>加一</button>
      <button onClick={() => dispatch(sub())}>减一</button>
      {/* 加三 */}
      <button onClick={() => dispatch(addNum(3))}>加三</button>
    </div>
  );
}

异步操作

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

englishStore.js

java 复制代码
import { createSlice } from "@reduxjs/toolkit";
const englishStore = createSlice({
  name: "englishstore",
  // 初始化状态
  initialState: {
    // 英文内容
    content: "",
    // 中文内容
    note: "",
  },
  // 修改内容
  reducers: {
    changeEnglish(store, action) {
        console.log(action.payload);
      store.content = action.payload.content;
      store.note = action.payload.note;
    },
  },
});

// 结构出action对象中的方法
const { changeEnglish } = englishStore.actions;

// 异步请求
const fetchEnglish = () => {
  return async (dispatch) => {
    const res = await fetch("https://api.oioweb.cn/api/common/OneDayEnglish");
    const data = await res.json();
    console.log(data);
    // 修改状态
    dispatch(changeEnglish(data.result));
  };
};

// reducer函数
const englishReducer = englishStore.reducer;

// 导出
export default englishReducer;
export { fetchEnglish };

使用

java 复制代码
import { useEffect } from 'react';
import './App.css'
import { useSelector, useDispatch } from 'react-redux';
import { fetchEnglish } from './store/modules/englishStore';

function App() {

  const englishReducer = useSelector(state => state.english)
  const dispatch = useDispatch()

  useEffect(() => {
  // 触发异步请求
    dispatch(fetchEnglish())
  }, [dispatch])


  return (
    <div>
      <div>中文:{englishReducer.note}</div>
      <div>英文:{englishReducer.content}</div>
    </div>
  );
}

export default App
相关推荐
ZHOU_WUYI1 小时前
React与Docker中的MySQL进行交互
mysql·react.js·docker
霸王蟹3 小时前
React 19中如何向Vue那样自定义状态和方法暴露给父组件。
前端·javascript·学习·react.js·typescript
purpleseashell_Lili4 小时前
项目制作流程
react.js
GISer_Jing6 小时前
Vue 和 React 状态管理的性能优化策略对比
vue.js·react.js·性能优化
chenbin___14 小时前
react native text 显示 三行 超出部分 中间使用省略号
javascript·react native·react.js
霸王蟹1 天前
React Fiber 架构深度解析:时间切片与性能优化的核心引擎
前端·笔记·react.js·性能优化·架构·前端框架
outstanding木槿1 天前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
霸王蟹1 天前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹1 天前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
Coding的叶子2 天前
React Flow 节点事件处理实战:鼠标 / 键盘事件全解析(含节点交互代码示例)
react.js·交互·鼠标事件·fgai·react agent