React状态管理 | 青训营笔记

88 阅读2分钟

React状态管理 | 青训营笔记

什么是状态管理

状态管理本身,解决的就是这种潜逃地狱的问题,解决的是跨层级组件之间的数据通信和状态共享

状态管理工具的本质:管理共享内存中的状态

  • 共享内存
  • 管理状态
  • 页面通信
  • 组件通信
  • 刷新失效?

详细定义:单页应用的各个组件本身是共享内存的,如果将状态保存在内存中,就可以读写统一内存中的变量,,从而达到状态共享的目的。

状态管理工具简介
  • React自带:Local State(props) 和 context
  • 单向数据流:Flux、Redux
  • 双向数据绑定:Mobx
  • 原子型状态管理:Recoil、Jotai
  • 异步操作密集型:Rxjs

1、Local State(props):组件级别的局部状态

import {useState} from 'react'
const Hello = () => {
    const [name, setName] = useState('tom')
    return <>Hello, {name}</>
}

只在Hello组件中生效,当组件创建时初始化和生效,组件销毁时失效

但是当一个父组件嵌套十几层子组件的时候,子页面和子页面之间的通信,React本身提供了Context

2、Context

function useCounter() {
    // 状态、属性
    let [count, setCount] = useState(0)
    let decrement = () => setCount(count-1)
    let increment = () => setCount(count+1)
    return { count, decrement, increment }
}
let Counter = createContext(null)
function CounterDisplay() {
    let counter = useContext(Counter)
    return <div>
        <button onClick={counter.decrement}>-</button>
        <button onClick={counter.decrement}>-</button>
        <p>{counter.count}</p>
    </div>
}
function App() {
    let counter = useCounter()
    return
        <Counter.Provider value={counter}>
            <CounterDisplay />
            <OtherDisplay />
        </Counter.Provider>
}

OtherDisplay 组件中没有用到context里的value,但是当context值变换的时候,OtherDisplay也会重新渲染

  • Context相当于他全局变量,难以追溯数据的变更情况
  • 使用Context的组件内部耦合度太高,不利于组件的复用和单元测试
  • 会产生不必要的更新,会穿透memo和dependicies
  • 多个Context会存在层层嵌套的问题

3、Redux

在Redux上解构了Action和Dispatcher

export default addTodo(text) {
    return {
        type: ActionTypes.ADD,
        text: text
    }
}
let action = {
    type: 'add'
}
dispatcher.dispatch(action)
dispatcher.register((action) => {
    switch(action.type) {
        case 'add':
            ...
            break;
    }
})
  • 单一数据源:在redux中,整个应用的全局State,都会保存在一个store中,一个单一数据源store tree 也简化了应用的调试和监控
  • store中的state是只读的:我们不能直接修改store中的state,唯一能改变state的方式就是通过action
  • 使用纯函数来执行修改:接受纯函数来接受action,该纯函数叫reducer,可以改变store中的state