該案例是以中間件調用 nodejs 的公共接口,實現一個數據列表。javascript
源碼下載:https://github.com/dk-lan/rea... html
效果預覽java
用戶名和密碼都爲空node
源碼下載後執行下面步驟例可查看效果react
npm install
npm start
在 Redux 中使用中間件能夠解決不少問題,但也會有個致命的問題,那就是在同一個組件中屢次調用同一個組件,那就會形成做用域污染。git
本案例中是這樣的場景:github
cnode
中動態加載數據,在該組件中還會有一個輸入框,點擊時彈窗動態加載一個數據列表,雙擊數據列表進行填充到對應的輸入框中datagrid
,用於動態加載數據,ajax 加載使用了中間件。modal
,該組件用到彈窗加載一個數據列表datagrid
cnode
中調用了組件datagrid
,<Datagrid config={this.props.cnode.config}/>
cnode
中同時調用了組件modal
,而組件modal
又調用了組件datagrid
。datagrid
的數據源就會衝突,後面加載的數據衝突了前面加載的。datagrid
時給一個別名name
,別名不能重複,用於做用域隔離static defaultProps = { cnode: { config: { url: 'https://cnodejs.org/api/v1/topics', data: {page: 1, limit: 10}, cols: ['title', 'reply_count', 'top', 'create_at', 'last_reply_at'], name: 'cnode' } }, modal: { config: { type: 'datagrid', url: 'https://cnodejs.org/api/v1/topics', data: {page: 3, limit: 5}, cols: ['title'], name: 'modal' } } }
Action
中將別名name
派發到中間件export function refresh(_config){ return { types: [constants.Requesting, constants.Requested, constants.RequestError], url: _config.url, method: _config.method || 'get', data: _config.data || {}, name: _config.name } }
name
一派發到Reducer
let _action = { type: constants.Requested, name, result: res.data } dispatch(_action)
Reducer
中兼容有別名和沒別名的狀況,若是有別名,就將數據源做用域隔離if(action.name){ _state[action.name] = _state[action.name] || {}; _state[action.name].dataset = action.result; } else { _state.dataset = action.result; }
DatagridComponent
中判斷是否有別名,兼容有別名和沒別名的狀況,分別操做不一樣的數據源let ds = this.props.dataset; let name = this.props.config.name; if(name){ ds = ds[name] ? ds[name].dataset : [] } else { ds = ds.dataset || []; }