在内部.map中反应onClick然后更改另一个兄弟组件中的数据

时间:2016-01-22 02:34:04

标签: reactjs

第1天使用React,我没有找到办法获得<按钮> onClick = {this.props.handleClickPlay}> Play< /按钮>播放音频。如果我在{audioListNodes}下移动它按钮工作正常。我想让每个链接最终播放一个单独的音频文件,但是现在只是播放同一个文件是一个胜利,但将事件处理程序移动到列表中会将其杀死。我假设它是因为它不再引用AudioList而是引用var数据?一旦我按下按钮,我如何识别单击哪个按钮并更改AudioObject源?

    var data = [
    {voice: "Drew", file:"Drew.mp3", volume: 90},
    {voice: "Chris", file:"Chris.mp3", volume: 85},
    {voice: "Patrick", file:"Patrick.mp3", volume: 85},
    {voice: "Everett", file:"Everett.mp3", volume: 60},
    ];

    var AudioList = React.createClass({
      render: function() {
        var audioListNodes = this.props.data.map(function(el, index) {
          return (
            <div author={el.voice}>
              {el.file}
                <button onClick={this.props.handleClickPlay}>Play</button>
            </div>
          );
        });  
        return (
          <div className="audioList">
            {audioListNodes}
          </div>
        );
      }
    });
    var AudioObject = React.createClass({
        play: function () {
            var audio = this.getDOMNode();
            audio.load();
            audio.play();
        },
        render: function() {
            return (
                <audio preload="auto" controls="true" autoPlay="">
                    <source src='female/DeDe Splaingard.mp3'></source>
                    Your browser does not support audio.
                </audio>
            );
        } 
    });
    var App = React.createClass({
        handleClickPlay: function() {
            this.refs.audioObject.play()
        },
        render: function() {
            return (
                <div>
                    <AudioObject ref="audioObject" />
                    <AudioList data={this.props.data} handleClickPlay={this.handleClickPlay} />
                </div>
            );
        } 
    }); 
    ReactDOM.render(
      <App data={data} />,
      document.getElementById('content')
    );

2 个答案:

答案 0 :(得分:12)

由于.map内的上下文发生了变化,您必须bind(this)到匿名函数:

var audioListNodes = this.props.data.map(function(el, index) {
  return (
    <div author={el.voice}>
      {el.file}
      <button onClick={this.props.handleClickPlay}>Play</button>
    </div>
  );
}.bind(this));

另一种选择是开始使用ES6箭头函数,它通过词法传递this

var audioListNodes = this.props.data.map((el, index) => {
  return (
    <div author={el.voice}>
      {el.file}
      <button onClick={this.props.handleClickPlay}>Play</button>
    </div>
  );
});

正如@Henrik Andersson在评论中提到的,您也可以将this直接传递给map

var audioListNodes = this.props.data.map(function(el, index) {
  return (
    <div author={el.voice}>
      {el.file}
      <button onClick={this.props.handleClickPlay}>Play</button>
    </div>
  );
}, this);

答案 1 :(得分:4)

你应该把它添加到.map(),因为在.map()内部,这是指在严格模式下窗口或未定义。

var audioListNodes = this.props.data.map(function(el, index) {
      return (
        <div author={el.voice}>
          {el.file}
            <button onClick={this.props.handleClickPlay}>Play</button>
        </div>
      );
}, this);
 ! here !