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;
相关推荐
YFF菲菲兔1 小时前
React 基础事件插件
react.js
易知微EasyV数据可视化2 小时前
定制化3D组件开发:打造差异化孪生体验
前端·人工智能·经验分享·数字孪生
多加点辣也没关系2 小时前
JavaScript|第24章:事件循环与并发模型
开发语言·javascript·ecmascript
前端炒粉3 小时前
Vue2 SSE 流式对话完整前端代码
前端·sse·流式输出
BIM云平台开发3 小时前
【App.vue里跟踪页面跳转和用户ID】
开发语言·前端·javascript
汪汪大队u3 小时前
Zabbix 6.0 部署踩坑记:从启动失败到 Web 成功访问
前端·zabbix
顺颂时绥_13 小时前
new Set 过滤数据实战
前端
赵大仁3 小时前
Next.js + Vercel AI SDK 实战:30 分钟搭出流式 Chat 页面
前端·ai·实战·react·next.js·vercel
云空4 小时前
《Three.js 完整版3D魔方:带贴纸+中心固定+自动求解复原》
前端·javascript·3d·three.js