首页 文章

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

提问于
浏览
0

我正在使用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

    我在最近的帖子Practical Redux, Part 10: Managing Modals and Context Menus中提到过这类问题 .

    基本方法是:

    • 将回调函数作为模态组件的支柱传递(这将起作用,但如果您从Redux状态驱动模态显示,则不鼓励将函数置于Redux状态)

    • 创建一个"pre-built"动作,将其作为道具传递给模态,并将模态调度作为"return value"时关闭

    • 使用像redux-promising-modals这样的中间件来跟踪打开和关闭模态的操作,并在关闭模态时使用它返回的promises来处理"return values" .

相关问题