学习React 的第九天 Redux

113 阅读3分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

1. 简介

Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。

Redux 本身是一个独立的库,可以与任何 UI 层或框架一起使用。

Redux 就类似 Vue中的 Vuex

2. 代码学习

1. 安装

pnpm i redux react-redux
  1. Redux 本身是一个独立的库.
  2. React-Redux 是 React 的官方 Redux UI 绑定库.
  3. 想要同时使用 Redux 和 React,使用 React-Redux 来绑定这两个库.

2. 创建Store,控制状态的方法

  1. 新建store文件
  2. 再创建index.tx文件
     import { legacy_createStore as createStore } from 'redux'
    
     export interface stateType {
         name: string,
         age: number
     }
    
     interface actionType {
         type: string,
         payload: any
     }
     const userStore = (state: stateType = {name: '张三', age: 20 }, action: actionType) =>{
         switch (action.type) {
             case 'setName':
                 console.log("修改name")
                 return {
                     ...state,
                     name: action.payload
                 }
             case 'setAge':
                 console.log("修改age")
                 return {
                     ...state,
                     age: action.payload
                 }
             default:
                 return state
         }
     }
     export default createStore(userStore)
    
  3. state 需要共享的数据
  4. action 修改 state的动作
  5. action 中有两个属性,type 是类型, payload是更新的最新值

3. 绑定store

  1. 全局状态必须放在跟组件 main.tsx文件中
     import React from 'react'
     import ReactDOM from 'react-dom/client'
     import App from './App'
     import { Provider } from 'react-redux'
     import store from './store'

     ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
         <Provider store={store}>
             <App/>
         </Provider>
     )

4. 在组件中使用

  1. 获取数据

useSelector 用于获取全局状态

import { useSelector } from "react-redux";
import { stateType } from '../store'

export default function Header() {

   // 获取 redux 中定义的全局状态
   const user = useSelector(state => state as stateType)

   return <div>
       <p>用户: {user.name}, {user.age}</p>
       <ChangeBtn/>
   </div>
}
  1. 修改数据

useDispatch 用于获取全局状态

import { useDispatch } from "react-redux";

function ChangeBtn() {
    const dispatch = useDispatch()

    return <>
        <button onClick={() => dispatch({ type: 'setName', payload: '王五' })}>修改用户名</button>
    </>
}
  1. 以上只是简单的使用如果status有多个对象
  2. 定义复制性的store
export interface stateType {
    user: {
        name: string,
        age: number
    }
    job: { name: string, total: number }
}

interface actionType {
    type: string,
    payload: any
}

const userStore = (state: stateType = {
    user: { name: '张三', age: 20 },
    job: { name: '程序员', total: 50 }
}, action: actionType) => {
    switch (action.type) {
        case 'setUserName':
            return {
                ...state,
                user: {
                    ...state.user,
                    name: action.payload
                }
            }
        case 'setAge':
            return {
                ...state,
                user: action.payload
            }
        default:
            return state

    }
}

export default createStore(userStore)
function ChangeBtn() {
    const { user } = useSelector(state => state as stateType)
    const dispatch = useDispatch()

    return <>
        <button onClick={() => dispatch({ type: 'setUserName', payload: '王五' })}>修改用户名</button>
        <button onClick={() => dispatch({ type: 'setAge', payload: { ...user, age: 30 } })}>修改age</button>
    </>
}

5. 多个store

在开发中如果按照上面写法 数据如果再多一些会越来越难以维护,action会变得庞大无比,我们就应该创建多个store,拆分刚才store

  1. 重新创建store
export interface stateType {
    user: {
        name: string,
        age: number
    }
    job: { name: string, total: number }
}

interface actionType {
    type: string,
    payload: any
}

const userStore = (state: stateType['user'] = {
    name: '张三', age: 20
}, action: actionType) => {
    switch (action.type) {
        case 'setUserName':
            console.log("修改name")
            return {
                ...state,
                name: action.payload
            }
        case 'setUserAge':
            return {
                ...state,
                age: action.payload
            }
        default:
            return state

    }
}

const jonStore = (state: stateType['job'] = {
    name: '程序员', total: 10
}, action: actionType) => {
    switch (action.type) {
        case 'setJobName':
            return {
                ...state,
                name: action.payload
            }
        case 'setJobTotal':
            return {
                ...state,
                total: action.payload
            }
        default:
            return state

    }
}
  1. 合并reducer
const reducers = combineReducers({
    user: userStore,
    job: jonStore
})
  1. 需要注意action中的type不能同名
  2. 这样好处便于维护一些

3. 总结

  1. 以一个简单的用例快速入门了 redux 状态管理工具
  2. 在使用中总觉得还是有一点差强人意,但是在社区中还有其他的替换方案 例如 Mobx
  3. 他们本质上都是解决态管理混乱,无法有效同步的问题