用Redux来举行组件间通信
迷惑
之前在做项目的时刻,一向会碰到一个搅扰我的题目,两个相互自力的子组件怎样通信?
假定如今构造以下
ListItem
是一个todoList组件,内里有一个删除操纵
,点击增添备注时会弹出模态框,让用户举行填写。
根据之前的写法,要像如许
父组件要通报一个props:
showDelModal
,以便于todoItem
调起模态框。同时,父组件要通报
confirm
、cancel
两个props给Modal
组件,用于吸收Modal
组件点击了确认照样作废。
假定如许的子组件较多,那父组件就显得很痴肥,浏览代码也很贫苦,我愿望挪用确认模态框时就像挪用window.confirm
一样,逻辑清楚,不需要这么多的回调函数。
完成
用了redux后,发明我的思绪是能够被完成的,下面讲一下历程,建媾和代码一同看。
我们新建一个modal组件
import React from 'react';
import ReactDOM from 'react-dom';
import '../stylus/modal.styl';
export default class ConfirmModal extends React.Component {
constructor() {
super();
}
componentDidMount() {
}
onConfirm() {
this.props.resolve(true);
}
onCancel() {
this.props.reject(false);
}
render() {
return (
<div className="modal" style={{display: this.props.show ? 'block' : 'none'}}>
<div className="modal-inner">
<h3>确认删除?</h3>
<div className="btn-action">
<button className="pure-button" onClick={this.onConfirm.bind(this)}>确认</button>
<button className="pure-button" onClick={this.onCancel.bind(this)}>作废</button>
</div>
</div>
</div>
)
}
}
修正原有todoItem的del函数
//重点在这
waitForConfirm() {
let {store} = this.context;
return new Promise((resolve, reject) => {
store.dispatch({
type: 'SHOW_MODAL',
payload: {
show: true,
resolve,
reject
}
})
});
}
closeModal() {
let {store} = this.context;
store.dispatch({
type: 'CLOSE_MODAL',
payload: {}
})
}
async del() {
let {index} = this.props;
let ret = await this.waitForConfirm().catch(e => {
return false;
});
if (!ret) {
this.closeModal();
return false;
}
this.props.handleDelTodo(index);
this.closeModal();
}
原有的reducer上增添数据
/**
* Created by chenchen on 2017/2/4.
*/
import {combineReducers} from 'redux';
function todoList(todolist = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [...todolist, ...action.payload];
return todolist;
case 'DEL_TODO':
return todolist.filter((val, index) => index !== action.payload);
default:
return todolist;
}
}
//确认删除模态框
function confirmModalData(data = {
show: false,
resolve: null,
reject: null
}, action) {
let d = {};
switch (action.type) {
case 'SHOW_MODAL':
return Object.assign(d, data, action.payload);
case 'CLOSE_MODAL':
return Object.assign(d, data, {show: false});
default:
return data;
}
}
//... 其他reducer
export default combineReducers({todoList, confirmModalData});
下面这类写法,是否是就很像window.confirm
呢?
let ret = await this.waitForConfirm().catch(e => {
return false;
});
道理
实在道理照样用了回调函数,只是将其包裹在一个Promise对象中:
把Modal的confirm
和cancel
放入Redux的store中,每一个todoItem举行删除操纵时,会替代store中的resolve
和reject
函数,并返回一个Promise对象,而Modal举行确认和作废操纵,会挪用store中的resolve
和reject
函数,如许,todoItem守候模态框的Promise就返回啦,经由过程返回值就能够推断是确认和作废操纵了。
如许的优点就是,纵然组件的层级再深,也不会增添数据通报的复杂度,由于二者是直接经由过程store来通信的。