背景
使用 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>
...