先把代码记录下来,不注重讲解。
不懂的可以先了解一下基础知识
基本代码
类型定义
/store/type.d.ts
数据结构类型定义
export interface StateProps {
DETAIL?: DataType
}
export type StatePropsKey = keyof StateProps
自定义reducer方法类型定义
interface updateAction {
type: 'UPDATE'
value: { field: StatePropsKey, data: any }
}
interface updateSomeAction {
type: 'UPDATE_SOME'
value: StateProps
}
interface clearAction {
type: 'CLEAR'
}
export type ReducerActionProps = updateAction | updateSomeAction | clearAction
初始化数据结构
/store/initState.ts
import { StateProps } from './type'
// 初始状态
const initState: StateProps = {
DETAIL: undefined
}
export default initState
useReducer 实现方法
/store/useReducerAction.ts
import { useReducer } from 'react'
import { cloneDeep } from 'lodash'
import initState from './initState'
import {
StateProps,
StatePropsKey,
ReducerActionProps,
} from './type'
const reducer = (
prevState: StateProps,
action: ReducerActionProps,
) => {
const { type } = action
// 不改变原始state
const state: StateProps = { ...prevState }
switch (type) {
// 更新
case 'UPDATE':
state[action.value.field] = action.value.data
break
// 更新部分
case 'UPDATE_SOME':
Object.keys(action.value || {}).forEach((key: any) => {
const temp = key as StatePropsKey
// @ts-ignore
state[temp] = action.value[temp]
// state[key as StatePropsKey] = action.value[key as StatePropsKey]
})
break
// 清空
case 'CLEAR':
return cloneDeep(initState)
default:
throw new Error('无效类型')
}
return state
}
function useReducerAction () {
// 使用useReducer将 reducer和initState结合
const [ state, dispatch ] = useReducer(reducer, cloneDeep(initState))
return {
state,
dispatch,
}
}
export default useReducerAction
创建Context 并结合 useReducer 的实现方法
/store/context.tsx
import React, { createContext } from 'react'
import { cloneDeep } from 'lodash'
import useReducerAction from './useReducerAction'
import initState from './initState'
import { StateProps, ReducerActionProps } from './type'
const Context = createContext<{
state: StateProps,
dispatch: React.Dispatch<ReducerActionProps>
}>({
state: cloneDeep(initState),
dispatch: () => {
throw new Error("GlobalContext 未定义")
}
})
type Props = {
children: React.ReactNode
}
export const Provider = (props: Props) => {
const { state, dispatch } = useReducerAction()
return (
<Context.Provider value={{ state, dispatch }}>
{ props.children }
</Context.Provider>
)
}
export default {
Context,
Provider
}
加入状态管理
定义操作方法 /store/useAction.tsx
import { useContext } from 'react'
import context from './context'
import { StateProps, StatePropsKey } from './type'
/**
* 事件处理
*
* 使用时请使用 hooks 方式,如useActions
* @returns
*/
const actions = () => {
const { state, dispatch } = useContext(context.Context)
/**
* 更新数据
* @param field 数据类型
* @param data 数据
*/
const update = (field: StatePropsKey, data: any) => dispatch({ type: 'UPDATE', value: { field, data } })
const updateSome = (data: StateProps) => dispatch({ type: 'UPDATE_SOME', value: data })
const clear = () => dispatch({ type: 'CLEAR' })
const init = () => {
clear()
}
return {
state,
method: {
update,
updateSome,
clear,
init,
}
}
}
export default actions
根组件加入状态管理
import { FC, useEffect } from 'react'
import Context from './store/context'
interface CanvasProps {
}
const Canvas: FC<CanvasProps> = (props) => {
const { state, method } = useAction()
useEffect(() => {
method.init()
return () => {
method.clear()
}
}, [])
return <div></div>
}
const connect: FC<CanvasProps> = () => {
return <Context.Provider>
<Canvas />
</Context.Provider>
}
export default connect