反应模式弹出窗口更改数据后,Reactjs刷新父级

时间:2017-08-03 01:22:10

标签: reactjs redux react-modal

我正在使用react模式在我的一个组件上设置弹出窗口。我有一个组件,使用react模式渲染div。我的父组件在加载模式组件时将isOpen设置为false。单击父集上的链接isOpen为true并导致模式弹出窗口打开。

我在打开的弹出窗口中更改了我的数据,然后保存更改并在单击关闭按钮时关闭模型。

我正在使用redux设置,其中action和reducers处理数据更改和状态更改。

从概念上讲,如何更新父级以显示弹出窗口所做的更改?不能使用动作更改我的数据会导致存储重新生成并因此更新组件中的数据,或者我必须明确地刷新"保存后我的商店?我的问题是,现在当弹出窗口关闭时,它并没有让任何类型的"刷新"在DataView组件上。

以下组件:

DataView组件

import React from 'react';
import DataView from './MonthView.js';
import DataViewPopup from './MonthViewPopup.js';
import { connect } from 'react-redux';
import { getAction } from '../actions/actions.js';
import { getActionAll } from '../actions/actions.js';
import { getPopupData } from '../actions/actions.js';

class DataViewContainer extends React.Component {
  constructor() {
    super();

    this.popupCategory = undefined;
    this.popupMonth = undefined;

    this.state = {
      detailPopup : false,
      refreshView: false
    }

  this.handleAddYear = this.handleAddYear.bind(this);
  this.handleSubtractYear = this.handleSubtractYear.bind(this);
  this.handleGetDetail = this.handleGetDetail.bind(this);

  }

  componentDidMount() {
   this.props.getAction(2016);
   this.props.getActionAll(2016);
  }

  render() {

     return (
        <div className="row">
          <div className="col-sm-8">
              <MonthView transactions={this.props.storeData.storeData} selectedYear={this.props.storeData.selectedYear} onAddYear={this.handleAddYear} onSubtractYear={this.handleSubtractYear} onHandleGetDetail={this.handleGetDetail} />
          </div>
          <div className="col-sm-4">
              <MonthViewPopup modalActive={this.state.detailPopup} transactions={this.props.storePopupData.getPopupData} selectedYear={this.props.storeTransactions.selectedYear} category={this.popupCategory} month={this.popupMonth}/>
          </div>
        </div>
      ) 

  }

  handleGetDetail(category,month) {

    console.log("props inside handleGetDetail:  ", this.props);

    this.popupCategory = category;
    this.popupMonth = month;
    let popupYear = this.props.storeTransactions.selectedYear

    this.props.getPopupData(popupYear, month, category);

    this.setState({ detailPopup: true}, function () {});

  }

}


const mapStateToProps = (state) => ({
  storeData: state.storeData,
  storePopupData: state.storePopupData,
  storeDataAll: state.storeDataAll
});

export default connect(mapStateToProps, {getAction,getActionAll,getPopupData})(DataViewContainer);

DataViewPopup组件

import React from 'react';
import Modal from 'react-modal';
import { connect } from 'react-redux';

import { saveAction } from '../actions/actions.js';
import { getActionAll } from '../actions/actions.js';

class DataViewPopup extends React.Component {

  constructor (props) {
    super(props)

    this.editedData = new Map(); 

    this.state = {
      modalIsOpen: false
    };

    this.openModal = this.openModal.bind(this);
    this.afterOpenModal = this.afterOpenModal.bind(this);
    this.closeModal = this.closeModal.bind(this);

    this.renderFilteredTransactions = this.renderFilteredTransactions.bind(this);

  }

 openModal() {
    this.setState({modalIsOpen: true});
  }

  afterOpenModal () {
    console.log("inside afterOpenModal");
  }

  closeModal () {

    this.props.saveTransactions(this.editedData);

    this.editedData = new Map();

    this.setState({  modalIsOpen: false }, function () {});

  }
  componentWillUnmount() {

    this.props.getDataAll(); // i tried this but it does not work because the component (modal popup) is still mounted, but just not visible

    //this.props.refreshParent();

  }


   componentWillReceiveProps(nextProps){

    if (nextProps.modalActive === true) {
         this.openModal();
         return;
      }

    }

    render () {
        return  <div>
            <Modal
            isOpen={this.state.modalIsOpen}
            //isOpen={this.modalActive}//not needed as is currently setup
            onAfterOpen={this.afterOpenModal}
            onRequestClose={this.closeModal}
            //style={customStyles}
            contentLabel="Example Modal"
            >

            <button onClick={this.closeModal}>close</button>

            {this.renderFilteredTransactions(this.props.data,this.props.category,this.props.month)};
            </Modal>
        </div>
    } 

    renderFilteredTransactions(trans,category,month){
        return <div>
            <table>
                <tbody className="mo-tblBody">
                    {trans && trans.map((data,index) =>
                        <tr key={data.transid}>
                            <td>{data.transid}</td>
                            <td>
                              {this.renderCategory(data.category,index,data.transid)}
                            </td>
                        </tr>
                    )}
                </tbody>
            </table>
        </div>

    }

    handleCategoryChange(value,transIndex,transId){

      let trans = JSON.parse(JSON.stringify(this.props.transactions));

      //add or updated transaction to this.editedTransactions based on whether or not the transid already exists
      trans.filter(item => item.transid === transId)
      .map(item => this.editedData.set(transId, 
                  Object.assign({}, item, { category: value })));

    }

}

const mapStateToProps = (state) => {
  return {storeDataAll: state.storeDataAll,
    storeSaveData: state.storeSaveData
  }
};

export default connect(mapStateToProps, {getDataAll,saveData})(DataViewPopup);

1 个答案:

答案 0 :(得分:0)

我在最近的帖子Practical Redux, Part 10: Managing Modals and Context Menus中介绍了这类问题。

基本方法是:

  • 将回调函数作为模态组件的支柱传递(这将起作用,但如果您从Redux状态驱动模态显示,则不鼓励将函数置于Redux状态)
  • 创建&#34;预建&#34;动作,将其作为道具传递到模态,并将模态调度作为&#34;返回值&#34;当它关闭时
  • 使用像redux-promising-modals这样的中间件来跟踪打开和关闭模态的操作,并使用它返回的承诺来处理&#34;返回值&#34;当模态关闭时。