背景
使用 yarn create umi
创建了一个干净的基于umi+dva的react项目。在遇到组件之间的通讯时,需要使用到dva。如何使用dva实现组件之间的通讯呢?
步骤如下:
1. model定义
export default {
namespace:'settingDrawer',
state: {
visible: false
},
reducers: {
'visible'(state:any, { payload }) {
let newState = {...state}
newState.visible = payload.visible
return newState
},
},
}
reducers解析
reducers下的方法,即将来可使用dispatch({type:xxx, payload:xxx})
实现状态的修改,即组件间的通讯(注意return返回的state值,这里有坑,正确返回了state,组件却未正确更新看这里)
ps: 注意
该model文件必须要按umi约定的目录或规则中,否则无法使用
默认情况下全局model放在/src/models
下,局部页面用的放在/src/page/xxx/model.js
2. react UI componet相关的代码
// 引用dva
import React, {Component} from 'react'
import { connect } from 'dva'
class SettingDrawer extends Component {
onClose = () => {
const { dispatch } = this.props
dispatch({type:'settingDrawer/visible', payload:{ visible: false}})
}
render() {
const { settingDrawer: { visible } } = this.props
return (
<div>
<Drawer
title="Basic Drawer"
visible={visible}
onClose={this.onClose}
>
<p>Some contents...</p>
</Drawer>
</div>
);
}
}
// 使用connect 关联组件
export default connect(({ settingDrawer }:{ settingDrawer:any})=>({ settingDrawer }))(SettingDrawer)
connect方法解析
connect方法本身返回的是一个 React组件,所以export default 出来的也是一个组件,没毛病
connect方法注意,用了两次(),第一个()内的是一个映射方法,这个映射方法带一个参数,这个参数就是model模型中定义的状态,映射方法返回数据,将来就会自动传到第二个括号中的组件中的属性。
也就是,在这个组件中,可以从this.props
中获取model中的state的数据的关键所以
如何在别的组件未定义model的组件中,也能使用dispatch去触发dva中管理的状态呢?
答案是使用connect
,代码如下:
import React, {Component} from 'react'
import { connect } from 'dva'
class MyCom extends Component{
}
export default connect()(MyCom )
问题笔记(万事具备却报错)
本以为完成以上操作后,就可正常使用了,谁知道,会报如下错:
这里的背景是这样子的:笔者开发是一个模块,模块中又有许多小模块,这些小模块之间需要通讯。即开发的代码是放在src/componets/xxxx/xxx
中的。(这里还留下一个小小遗憾,就上面的model是需要放在默认的src/models
下放可正常使用的,还没实现与这个小组件放在一起)
Uncaught Error: Could not find “store” in either the context or props of “Connect(SettingDrawer)”. Either wrap the root component in a , or explicitly pass “store” as a prop to “Connect(SettingDrawer)”.
这是什么问题呢?原来上面写的SettingDrawer
组件 是需要被包裹在Provider容器中方可正常获取到redux的store的,store就是存储这些状态值的。
怎么解决?代码如下:
import { Provider } from 'react-redux'
...
<Provider store={window.g_app._store}>
<SettingDrawer />
</Provider>
...