文章目录
Redux
Redux 中的核心概念
Reducer
是一个用来改变 state 的纯函数,传入state 通过应用状态与 Action 推导出新的 state。
Action
Store
- 存储应用 state 以及用于触发 state 更新的 dispatch 方法等,单一的 Store 。
- Store 中提供了几个 API :
- store.getState(): 获取当前 state。
- store.dispatch(action): 用于 View 发出 Action。
- store.subscribe(listener): 设置监听函数,一旦 state 变化则执行该函数(若把视图更新函数作为 listener 传入,则可触发视图自动渲染)。
Redux 的特点
- 单向数据流
- 单一数据源 ,只有一个 Store 和 Vuex 一样
- state 是只读的,每次状态更新后返回一个新的 state
- Store中集成了 dispatch 方法,该方法是 View 发出 Action的唯一途径。
创建store/index.js 作为主文件
import { configureStore } from "@reduxjs/toolkit";
//子模块导入,可自定义多个
import counterStore from "./modules/counterStore";
// 创建store组合子模块
const store = configureStore({
reducer:{
counterStore,
}
})
export default store
创建子文件/store/modules/aadmin.js
import { createSlice } from "@reduxjs/toolkit";
const counterStore = createSlice({
name: "todos",
// 存储数据
initialState: {
count:0
},
// 方法逻辑函数
reducers: {
inscrement(state,action) {
state.count-=action.payload
},
decrement(state,{payload}) {
state.count+=payload
},
},
});
// 导出
export const { decrement, inscrement } = counterStore.actions;
export default counterStore.reducer;
导出index.js文件到根index.js使用
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.scss';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from "./store";
import { Provider } from "react-redux";
import { RouterProvider,router } from "./router";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* 绑定路由 */}
<RouterProvider router={router} >
{/* 绑定redux */}
<Provider store={store}>
<App />
</Provider>
</RouterProvider>
</React.StrictMode>
);
reportWebVitals();
使用Redux的方法useSelector,useDispatch两个hooks
import { useSelector,useDispatch } from "react-redux";
import { inscrement,decrement } from "./store/modules/counterStore";
import './App.css';
import Home from "./components/Home";
function App() {
// react-redux中间件导入 useSelector() 函数获取store参数
const {count} = useSelector(state=>state.counterStore)
// react-redux中间件导入 useSelector() 函数获取store函数使用
const dispach = useDispatch()
return (
<div
className="App active"
>
{count}
<button type="" onClick={()=>dispach(inscrement(10))}>++</button>
<button type="" onClick={()=>dispach(decrement(10))}>--</button>
<Home>
<span>12222</span>
</Home>
</div>
);
}
export default App;
zustand轻量状态管理
Zustand
- Zustand 是一个轻量级的状态管理库,用于 JavaScript 应用程序,特别是在 React 生态系统中。它提供了一个简单、可扩展的解决方案来中心化和管理应用程序的状态。
- 与其他状态管理解决方案(如 Redux 或 MobX)相比,Zustand 旨在提供更简洁的 API 和更少的样板代码。它允许你创建一个全局状态存储,并且可以在应用程序的任何地方访问和更新这个状态,而不需要像 Redux 那样编写大量的 action creators 和 reducers。
Zustand 的主要特点包括:
-
简洁的 API:创建 store 和访问 state 都非常直观。
-
React hooks:Zustand 与 React hooks 完美整合,使得在 React 组件中使用状态变得非常简单。
-
不可变更新:通过 Immer 库支持,Zustand 允许你以一种直观的方式更新复杂的状态对象。
-
中间件支持:可以使用中间件来添加额外的功能,例如日志记录、持久化等。
-
没有“单一真相来源”的限制:与 Redux 不同,Zustand 允许你创建多个独立的 store。
-
Zustand 是在 React 社区内广受欢迎的解决方案之一,适用于那些想要更简单状态管理工具的开发者。
解决的问题
Zustand 主要旨在解决以下问题:
-
简化状态管理:提供一个更直观的 API,通过避免 Redux 那样的冗余样板代码,使得状态管理更加简洁和直接。
-
更好的开发体验:通过使用 React Hooks,Zustand 使得在函数组件中访问和更新状态变得容易。
-
无拘无束:Zustand 允许创建多个独立的 store,不强制要求"单一真相来源",给予开发者更多的灵活性。
-
性能优化:Zustand 允许组件仅订阅状态的一部分,从而减少不必要的渲染和提高性能。
-
简单的状态共享:不需要复杂的上下文或提供者,状态可以跨组件和文件轻松共享。
-
中间件和增强功能:支持中间件,使得开发者可以轻松添加日志记录、持久化存储等增强功能。
-
适应现代 React 功能:考虑到了 React 的新特性,如 Concurrent Mode 和 Suspense,从而确保在现代 React 特性下的稳定性。
-
总之,Zustand 应运而生,旨在为开发者提供一个轻便、简单且功能强大的状态管理库,让状态管理变得更加易于使用和维护。
安装
npm i zustand -D
创建zustand/index.js文件
import { create } from 'zustand'
const useBearStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
}))
export {
useBearStore
}
使用
import { useMemo, useState } from "react"
import { useBearStore } from "../zustand/index";
const fib=(n)=>{
console.log('计算函数执行了');
if(n<3)
return 1
return fib(n - 2) + fib( n - 1)
}
function Index() {
const [count1,setCount1]=useState(0)
const result =useMemo(()=>{
fib(count1)
},[count1])
const [count2,setCount2]=useState(0)
const a = useBearStore(state=>state.bears)
const a1 = useBearStore(state=>state.increasePopulation)
return (
<div style={{color:'red'}}>
Index
<button type="" onClick={()=>setCount1(count1 +1)}>{count1}</button>
<button type="" onClick={()=>setCount2(count2 +1)}>{count2}</button>
<button type="" onClick={a1}>{a}</button>
{result}
</div>
)
}
export default Index;