无法读取属性' modalIsOpen'未定义的

时间:2015-12-25 07:51:42

标签: javascript ruby-on-rails ruby-on-rails-4 reactjs

我希望使用react-modal迭代一些数据,然后在单击按钮时将这些数据填充到模态中,它会根据单击的按钮弹出不同的值。希望这有道理吗?如果不是:

我迭代了几个数据,所以在每个循环中,我都有一个按钮。当我点击第一个按钮时,我得到了一些价值。当我点击按钮2时,我得到的值不同,但与按钮1的值不同。

var React = require('react');
var Modal = require('react-modal');

Cards = React.createClass({

getInitialState:function(){
      return{
          filteredData: this.props.data, // Im using react-rails to get this 'data'
          modalIsOpen: false
      }
  },

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

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

  handleModalCloseRequest: function() {
    // opportunity to validate something and keep the modal open even if it
    // requested to be closed
    this.setState({modalIsOpen: false});
  },

  handleInputChange: function() {
    this.setState({foo: 'bar'});
  },

render(){
 var cards=[];
 this.props.data.slice(0, 25).forEach(function(s) {
 cards.push(
  <div key={s.id}>
    <button className="button tiny radius" onClick={this.openModal}>view</button>
    <Modal
      closeTimeoutMS={150}
       isOpen={this.state.modalIsOpen}
       onRequestClose={this.handleModalCloseRequest}>
       <h1>{s.title}</h1>
       <button onClick={this.closeModal}>close</button>
        <div>{s.description}</div>
         <form>
          <input onChange={this.handleInputChange} />
          <input />
          <br/>              
          <button>{s.agree}</button>
         </form>
     </Modal>
  </div>
 )
 });

 return(
  {cards}
 )
}

});
module.exports = Cards;

如果我将<Modal></Modal>移动到render()一切正常,但我需要模态循环。有没有办法重写这个?

2 个答案:

答案 0 :(得分:1)

现在代码中有几个错误

1 组件必须只有一个根元素。,您应该将cards包装到元素

return (<div>
   {cards}
</div>);
.forEach this中的

2 指的是全局范围,但不指Cards Object ,.你应该设置this forEach,但是在这种情况下你可以使用.map它更合适,你可以设置this只传递第二个参数,就像这样

var cards = this.props.data.slice(0, 25).map(function(s) {
   // code ...
   // now this refers to Carts Object
}, this);
--^^^^^--

实施例

var Cards = React.createClass({

  getInitialState: function() {
    return{
      filteredData: this.props.data,
      modalIsOpen: false,
      modalData: {}
    }
  },

  openModal: function(data) {
    this.setState({
       modalData: data
    });
  },

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

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

  handleInputChange: function() {
    this.setState({foo: 'bar'});
  },

  render()  {
    var cards = this.props.data.slice(0, 25).map(function(s) {
      return (<div key={ s.id }>
        <button className="button tiny radius" 
            onClick={this.openModal.bind(this, s)}>view</button>
        <Modal closeTimeoutMS={150} 
            isOpen={this.state.modalIsOpen} 
            onRequestClose={this.handleModalCloseRequest}>
          <h1>{s.title}</h1>
          <button onClick={this.closeModal}>close</button>
          <div>{s.description}</div>
          <form>
            <input onChange={this.handleInputChange} />
            <input />
            <br />
            <button>{s.agree}</button>
          </form>
        </Modal>
      </div>)
    }, this);

    return (<div>
      {cards}
    </div>);
  }
});

答案 1 :(得分:1)

我将首先创建一个州currentData,以便<Modal />远离loop

getInitialState:function(){
    return{
        filteredData: this.props.data,
        modalIsOpen: false,
        currentData: {}
    }
},

然后我将创建一个单独的函数来创建模态的内容,我将其称为renderModalContent

renderModalContent: function(s) {
    return (
      <div>
          <h1>{s.title}</h1>
          <div>{s.description}</div>
          <form>
              <input onChange={this.handleInputChange} />
              <button>{s.agree}</button>
          </form>
      </div>
    )
},

这将是render方法

中的循环
    var cards = this.props.data.slice(0,25).map( (s, i) => {
        return (
            <div key={s.id}>
                <button className="button tiny radius" onClick={this.openModal.bind(this,s)}>View</button>
            </div>
        );
    });

您可以看到我this.openModalthis绑定。您openModal

openModal: function(s) {
    this.setState({modalIsOpen: true, currentData: s});
},

它正在使用this.setState因此绑定。 s是我传递给renderModalContent函数的参数,因此我们可以将其传递给this.setState({currentData})

这将是render方法的返回值

    var currentData = this.state.currentData;
    return(
        <div>
            { cards }                
            <Modal
                closeTimeoutMS={150}
                isOpen={this.state.modalIsOpen}
                onRequestClose={this.handleModalCloseRequest}>
                {
                    Object.keys(currentData).length > 0 ?
                      this.renderModalContent(currentData) :
                      null;
                }
                <button onClick={this.closeModal}>close</button>
            </Modal>
        </div>
        })
    )

编辑:删除bind @Alexander和@Sylar在评论中建议