Skip to content

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)
框架ReactVue
核心理念全局状态管理(Flux 架构)轻量级状态管理
API 复杂度较高(需要 actions, reducers较低(更直观,类似 Vue 语法)
数据管理方式不可变数据(Immutable State)可变数据(Mutable State)
修改状态方式通过 dispatch(action) 修改直接调用 store 的 actions
状态组织方式store.js 里集中管理每个 store 独立
官方推荐Redux ToolkitPinia(Vue3 官方推荐)
插件支持多(Redux DevTools, Middleware)少(但 Vue 生态兼容好)
学习曲线较陡(需要理解 dispatchreducers较低(和 Vue 语法一致)
适用场景大型应用,Redux 提供完整数据流管理Vue 项目中更轻量级的选择

🔹 总结

  • 如果你使用 Vue3,推荐使用 Pinia(更简洁,和 Vue 组合式 API 兼容)。
  • 如果你使用 React,推荐 Redux Toolkit(状态管理更强大,适合大规模项目)。
  • Redux 适用于复杂应用,Pinia 更适合 Vue 轻量级状态管理

ReduxPinia 之间,有许多相似的概念,下面是详细的对比和类比:


🔹 1. 核心 API 对比

Redux (React)Pinia (Vue)作用
reducersactions处理状态变更
createSlicedefineStore定义 Store(包含 state、actions、getters)
useSelectorstore.state / computed访问状态数据
useDispatchstore.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 封装 stateactions,更直观。

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)
定义 StorecreateSlice()defineStore()
状态存储initialStatestate
修改状态reducers (不可变)actions (可变)
访问状态useSelector(state => state.xxx)store.xxx
调用 ActionsuseDispatch() + dispatch(action)直接调用 store.action()
数据响应式手动订阅 (useSelector)自动响应式 (store.xxx)
使用场景大型应用,状态管理复杂Vue3 推荐,轻量简单

🔹 结论

  • Redux 适用于 React 应用,适合大规模状态管理(但较复杂)。
  • Pinia 适用于 Vue3,更符合 Vue 生态(响应式 & 简单易用)。
  • 如果你是 Vue 开发者,Pinia 比 Vuex 更现代化,更推荐使用!