react函数式组件使用redux

85 阅读2分钟

总体流程:

  1. 与vue不同,react的数据管理需要自己独立定义store,reducer,action,如果要支持异步,需引入thunk
  2. store相当于全局变量,需接收reducer变量, (?可能自动处理state数据的订阅及分发?)
  3. reducer相当于封装对state数据的逻辑处理,注意不可直接操作state,需返回新的state变量
  4. action是一个业务处理判断所需的obj数据,或者是一个接收dispatch作为参数的函数

1.首先安装 redux(核心) react-redux(引入hook支持) redux-thunk(支持异步函数)

npm install redux react-redux redux-thunk

2.配置store入口

// store/index.ts
import { applyMiddleware, legacy_createStore } from 'redux'
import reducer from './reducer'
import reduxThunk from 'redux-thunk';

const store = legacy_createStore(reducer,applyMiddleware(reduxThunk))
export default store

2-2.react入口根组件注入store

//  根组件要使用Provider注入store
      <Provider store= {store}>
        <App />
      </Provider>

3.配置reducer, 主要是对state数据的逻辑处理业务

//  reducer.ts

const initalState = {
    age: 18
}
export default  (state = initalState, action) => {
    switch(action.type){
        case 'addnum':  {
            let newState = {...state, age: state.age + 1}
            return newState
        };
        default : return initalState;
    }
}

4.触发state数据的改变,使用useDispatch分发事件,需传递action

import React from 'react';
import { Button } from 'antd';
import { useDispatch } from 'react-redux';
import { getAsyncDispatch } from './reducer.ts'

function Profile() {
  //定义store的分发事件, dispatch 参数可以直接传递action对象
  const dispatch = useDispatch
  
  const clickAdd = () => {
  // action类型一般默认为{type: string, value?: any}
     dispatch({type: 'addnum'})
  }
  // 模拟异步等待函数
const wait = async (s: number) => {
    return new Promise((resolve, reject) => {setTimeout(() => {resolve(s)}, s * 1000)})
}
// 当action是函数时,其自动接收dispatch作为参数传递给内部使用
const getAsyncDispatch =  () => {
      return async (dispatch: any) => {
       let nn = await wait(3)
       dispatch({type: 'addnum'})
  }
}

 const clickAdd2 = () => {
     //  当使用thunk后  action可以是一个函数
      dispatch(getAsyncDispatch() as any)
    }
  return (
      <Button type="primary"  onClick={ clickAdd2 }  >数字加一</Button>
  )
}

5.其他任意组件展示数据,使用useSelector获取数据,相当于订阅hook

import React from 'react';
import { Button } from 'antd';
import { useSelector } from 'react-redux';

const Userinfo: React.FC = () => { 
// 动态获取store的数据
const age  = useSelector((state: any) => state.age)
    return(
        <Button type="text">年龄{age}</Button>
    )
}

export default Userinfo;

6.上面只是简单使用示例,正式开发应该会抽离action成单独文件里的函数,或者后续更新toolkit用法