React(三)——Redux

一、概念

Redux是React里的集中状态管理工具,类似Vue里的pinia(vuex),可以独立于框架运行

二、准备环境

下载两个插件:Redux Toolkit(是一套工具集,简化书写方式)和react-dedux(链接React和Redux之间的中间件

下载命令npm i @reduxjs/toolkit react-redux

文件夹依旧是:

三、实现counter

1.注册

counterStore.js:

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

const counterSlice = createSlice({  
  name: 'counter',
  // state
  initialState: {
    value: 0,
  },
  // mutations + actions
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    // 这里不是React 组件而是Redux Toolkit所以可以直接修改state
    decrement: (state) => {
      state.value -= 1;
    },
  },
})

const { decrement, increment } = counterSlice.actions;
// 写在reducers里自动被redux放在了actions里,到时候以函数的形式导出
// vuex操作不得是this.$store.dispatch('decrement') ,redux直接dispatch(decrement()),因为设计成了函数

// 然后reducer是这一整个模块的代表,导出出去供别的模块去引入
const reducer = counterSlice.reducer;
export { decrement, increment, incrementByAmount };
//这个导出用于组件使用函数的
export default reducer;
//这个导出用于store用来注册的

decrement, increment就是Redux Toolkit 的 createSlice 自动生成 的 Action Creator。Action Creator 就是一个专门用来"生产" Action 对象的函数。

复制代码
export default reducer是默认导出,就像一把万能钥匙,别人要使用的时候直接说要那把万能钥匙,不用记的是什么名字的钥匙。别人导入的时候:import counterReducer from './counterSlice'(随便取名)只能导出一个
复制代码
export { 大门钥匙, 卧室钥匙, 书房钥匙 }这种就是没把钥匙都贴了标签。别人导入的时候:import { increment, decrement } from './counterSlice'(必须得是这个名字)可以导出多个

store/index.js:

复制代码
import {configureStore} from '@reduxjs/toolkit';
import counterReducer from './modules/counterStore';

const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

export default store;
//这里的导出给index.js去注册的

项目的index.js:

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

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

用这种<Provider标签报错<App />的方式是因为vuex有那种全局的this.$store可以全局挂载,但是react没有,就只能通过这种上下文的方式从上到下去传递

2.组件中使用store方法/数据

(1)useSelector

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

复制代码
import logo from './logo.svg';
import './App.css';
import { useSelector } from 'react-redux';

function App() {
  const counter = useSelector((state) => state.counter);
  console.log('counter:', counter); 
//{"value":0}
  return (
    <div className="App">
      111
    </div>
  );
}

export default App;

注意这里的state.counter是对应上面这个名称的,然后里面有下图的这个模块内定义的变量

(2)useDispatch

它的作用是生成提交action对象的dispath函数

复制代码
import logo from './logo.svg';
import './App.css';
import { useSelector,useDispatch } from 'react-redux';
import { decrement, increment, incrementByAmount } from './store/modules/counterStore';

function App() {
    const counter = useSelector((state) => state.counter);
  console.log('value:', counter); 
  const dispatch = useDispatch();

  return (
    <div className="App">
      <button onClick={() => dispatch(increment())}>+</button>
      {counter.value }
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}

export default App;

3.提交Action传参

在调用actionCreator的时候传参,参数会被传递到action对象的payload属性上

复制代码
 incrementByAmount: (state, action) => {
      state.value += action.payload;
    },

import logo from './logo.svg';
import './App.css';
import { useSelector,useDispatch } from 'react-redux';
import { decrement, increment, incrementByAmount } from './store/modules/counterStore';

function App() {
    const counter = useSelector((state) => state.counter);
  console.log('value:', counter); 
  const dispatch = useDispatch();

  return (
    <div className="App">
      <button onClick={() => dispatch(increment())}>+</button>
      {counter.value }
      <button onClick={() => dispatch(decrement())}>-</button>
      <button onClick={() => dispatch(incrementByAmount(10))}>+10</button>
    </div>
  );
}

export default App;
相关推荐
To_OC15 小时前
别再瞎写 React Router!7 个高频踩坑点一次性讲透
前端·javascript·react.js
岭南灯火17 小时前
前端通用交互式几何编辑器的开发经验
前端·设计模式·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 7 - 设计模式与原则
前端·设计模式·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 4 - 绘制、悬停与编辑
前端·设计模式·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 3 - 数据对象的设计
前端·javascript·架构
Jackson__17 小时前
从 LLM 到 Agent:一篇文章搞懂 AI 圈热词!
前端·agent·ai编程
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 2 - 交互事件流
前端·javascript·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 6 - 配套设施与工程化
前端·设计模式·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 5 - 辅助元素的设计
前端·设计模式·架构
岭南灯火17 小时前
前端通用交互式几何编辑器的设计法则 1 - 入口的对象及其成员
前端·javascript·架构