用Redux来进行组件间通讯
用Redux來進行組件間通訊
demo地址
疑惑
之前在做項目的時候,一直會遇到一個困擾我的問題,兩個互相獨立的子組件如何通訊?
假設現在結構如下
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;} }//... 其他reducerexport 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來通訊的。
總結
以上是生活随笔為你收集整理的用Redux来进行组件间通讯的全部內容,希望文章能夠幫你解決所遇到的問題。