Redux vs Pinia 概念对比
🔹 举例:Redux 和 Pinia 在 React & Vue 中的使用
1️⃣ Redux 示例(React)
安装 Redux Toolkit
bash
npm install @reduxjs/toolkit react-redux
📌 创建 Redux Store (store.js
)
javascript
import { configureStore, createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
},
});
export const { increment, decrement } = counterSlice.actions;
export const store = configureStore({ reducer: counterSlice.reducer });
📌 在 React 组件中使用 Redux
javascript
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "./store";
const Counter = () => {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
};
export default Counter;
📌 在 App.js
中使用 Provider
javascript
import React from "react";
import { Provider } from "react-redux";
import { store } from "./store";
import Counter from "./Counter";
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
export default App;
2️⃣ Pinia 示例(Vue)
安装 Pinia
bash
npm install pinia
📌 创建 Pinia Store (stores/counter.js
)
javascript
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
decrement() {
this.count--;
},
},
});
📌 在 Vue 组件中使用 Pinia
vue
<script setup>
import { useCounterStore } from "@/stores/counter";
const counter = useCounterStore();
</script>
<template>
<div>
<h1>{{ counter.count }}</h1>
<button @click="counter.increment()">+</button>
<button @click="counter.decrement()">-</button>
</div>
</template>
📌 在 main.js
中注册 Pinia
javascript
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
const app = createApp(App);
app.use(createPinia());
app.mount("#app");
🔹 Redux vs Pinia 图表对比
对比项 | Redux (React) | Pinia (Vue) |
---|---|---|
框架 | React | Vue |
核心理念 | 全局状态管理(Flux 架构) | 轻量级状态管理 |
API 复杂度 | 较高(需要 actions , reducers ) | 较低(更直观,类似 Vue 语法) |
数据管理方式 | 不可变数据(Immutable State) | 可变数据(Mutable State) |
修改状态方式 | 通过 dispatch(action) 修改 | 直接调用 store 的 actions |
状态组织方式 | store.js 里集中管理 | 每个 store 独立 |
官方推荐 | Redux Toolkit | Pinia(Vue3 官方推荐) |
插件支持 | 多(Redux DevTools, Middleware) | 少(但 Vue 生态兼容好) |
学习曲线 | 较陡(需要理解 dispatch 、reducers ) | 较低(和 Vue 语法一致) |
适用场景 | 大型应用,Redux 提供完整数据流管理 | Vue 项目中更轻量级的选择 |
🔹 总结
- 如果你使用 Vue3,推荐使用 Pinia(更简洁,和 Vue 组合式 API 兼容)。
- 如果你使用 React,推荐 Redux Toolkit(状态管理更强大,适合大规模项目)。
- Redux 适用于复杂应用,Pinia 更适合 Vue 轻量级状态管理。
在 Redux 和 Pinia 之间,有许多相似的概念,下面是详细的对比和类比:
🔹 1. 核心 API 对比
Redux (React) | Pinia (Vue) | 作用 |
---|---|---|
reducers | actions | 处理状态变更 |
createSlice | defineStore | 定义 Store(包含 state、actions、getters) |
useSelector | store.state / computed | 访问状态数据 |
useDispatch | store.actions | 调用 actions 以更新状态 |
🔹 2. API 代码对比
1️⃣ Redux: reducers
vs. Pinia: actions
Redux - 使用 reducers
处理状态
javascript
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1; // Redux Toolkit 允许直接修改 state
},
decrement: (state) => {
state.count -= 1;
},
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
Pinia - 使用 actions
处理状态
javascript
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++; // 直接修改状态
},
decrement() {
this.count--;
},
},
});
🔹 类比
- Redux 的
reducers
需要 纯函数,不能直接修改 state(但 Redux Toolkit 用Immer
允许直接修改)。 - Pinia 的
actions
可以直接修改 state,更符合 Vue 的响应式思维。
2️⃣ Redux: createSlice
vs. Pinia: defineStore
Redux - 使用 createSlice
定义 Store
javascript
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
},
});
export default counterSlice.reducer;
Pinia - 使用 defineStore
定义 Store
javascript
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
},
});
🔹 类比
createSlice
封装reducers
,可以自动生成 actions。defineStore
封装state
、actions
,更直观。
3️⃣ Redux: useSelector
vs. Pinia: store.state / computed
Redux - 访问 state
javascript
import { useSelector } from "react-redux";
const Counter = () => {
const count = useSelector((state) => state.counter.count);
return <h1>{count}</h1>;
};
Pinia - 访问 state
vue
<script setup>
import { useCounterStore } from "@/stores/counter";
const counter = useCounterStore();
</script>
<template>
<h1>{{ counter.count }}</h1>
</template>
🔹 类比
- Redux 通过
useSelector(state => state.xxx)
获取状态。 - Pinia 直接通过
store.xxx
访问状态(更直观)。
4️⃣ Redux: useDispatch
vs. Pinia: store.actions
Redux - 调用 dispatch
更新状态
javascript
import { useDispatch } from "react-redux";
import { increment } from "./store";
const Counter = () => {
const dispatch = useDispatch();
return <button onClick={() => dispatch(increment())}>+</button>;
};
Pinia - 直接调用 store.actions
vue
<script setup>
import { useCounterStore } from "@/stores/counter";
const counter = useCounterStore();
</script>
<template>
<button @click="counter.increment()">+</button>
</template>
🔹 类比
- Redux 需要
useDispatch()
调用 actions(间接修改 state)。 - Pinia 直接调用 store 的 actions(更直观)。
🔹 3. Redux vs. Pinia 总结
对比项 | Redux(React) | Pinia(Vue) |
---|---|---|
定义 Store | createSlice() | defineStore() |
状态存储 | initialState | state |
修改状态 | reducers (不可变) | actions (可变) |
访问状态 | useSelector(state => state.xxx) | store.xxx |
调用 Actions | useDispatch() + dispatch(action) | 直接调用 store.action() |
数据响应式 | 手动订阅 (useSelector ) | 自动响应式 (store.xxx ) |
使用场景 | 大型应用,状态管理复杂 | Vue3 推荐,轻量简单 |
🔹 结论
- Redux 适用于 React 应用,适合大规模状态管理(但较复杂)。
- Pinia 适用于 Vue3,更符合 Vue 生态(响应式 & 简单易用)。
- 如果你是 Vue 开发者,Pinia 比 Vuex 更现代化,更推荐使用!