umijs+react+dva——状态管理,实现非兄弟、父子组件传值以及回调
参考:
1.Umi】umi-max 中使用 Dva https://juejin.cn/post/7373606026027237413
我的项目是:umijs+react
效果:

1.安装dva
npm install dva
Dva 是一个基于 Redux、Redux-Saga 和 React-Router 的数据流管理框架。
2.umirc.ts文件中配置dva
export default defineConfig({ dva: {}, // 其他配置 })
3.创建 Model,在 Umi 项目的 src/models 目录下创建一个新的文件,例如 test-switch.ts,用于定义一个模型。test-switch.ts:
import { updateSwitchRequest } from '../api' // 自己封装的请求
export default {
namespace: 'testSwitch', // model 的命名空间,唯一标识符,对应 redux 中的 state key
state: {
switchVal: true, // 初始状态
},
// reducers 中处理同步逻辑,更新 state
reducers: {
onChangeSwitch(state: any, { payload: switchVal }) {
return {
...state,
switchVal,
}
},
},
// 异步更新仓库状态数据
effects: {
*fetchData({ payload }, { call, put }) {
try {
const response = yield call(updateSwitchRequest, payload) // 调用异步请求接口
yield put({ type: 'onChangeSwitch', payload: response.data }) // 触发对应的 reducer
} catch (err) {
console.log('err', err)
}
},
},
}
4.开关组件,SwitchComponent.tsx:
import { connect } from '@umijs/max'
import { useRequest } from '@umijs/max'
import { useDispatch } from '@umijs/max'
import { Switch } from 'antd'
import { useEffect, useState } from 'react'
import { querySwitchRequest } from '../api' // 自己封装的请求
export function mapStateToProps(state: any) {
const { switchVal } = state.testSwitch // testSwitch就是models命名空间名字
return {
switchVal, // 在这return,才能获取到
}
}
function SwitchComponent(props: any) {
const dispatch = useDispatch()
const [val, setVal] = useState<boolean>(false)
const { data } = useRequest(() => querySwitchRequest ())
dispatch({ type: 'testSwitch/onChangeSwitch', payload: data })
useEffect(() => {
if (props) {
setVal(props.switchVal)
}
}, [props])
return (
<>
<div>
开关组件
<Switch
value={val}
onChange={v => {
dispatch({ type: 'testSwitch/fetchData', payload: { enable: v } })
}}/>
</div>
</>
)
}
export default connect(mapStateToProps)(SwitchComponent)
5.页面中使用,父组件Parent.tsx:
import type { TabsProps } from 'antd'
import { Card, Tabs } from 'antd'
import { useCallback } from 'react'
import { useLocation, history, Outlet } from '@umijs/max'
import SwitchComponent from '../components/switch-component'
const items: TabsProps['items'] = [
{
key: '/parent/child1',
label: '子组件1',
},
{
key: '/parent/child2',
label: '子组件2',
},
]
export default function ParentPage() {
const { pathname } = useLocation()
const handleChange = useCallback((key: string) => {
history.push(key)
}, [])
return (
<>
<Card title='父组件'>
<SwitchComponent />
<Tabs defaultActiveKey={pathname} items={items} onChange={handleChange} />
<Outlet />
</Card>
</>
)
}
6.子组件Child1.tsx:
import { connect } from '@umijs/max'
import { mapStateToProps } from '../../components/switch-component'
function WindowsPage(props: any) {
return <div>开关状态:{props.switchVal ? '开启' : '关闭'}</div>
}
export default connect(mapStateToProps)(WindowsPage)
7.route和目录层级:
{ name: '父菜单', path: '/parent', routes: [ { path: '/parent', redirect: '/parent/child1', }, { name: '子菜单1', path: '/parent/child1', component: '@/pages/parent/child1', }, { name: '子菜单2', path: '/parent/child2', component: '@/pages/parent/child2', }, ], },


浙公网安备 33010602011771号