Javascript React-触发表行上的单击事件

Javascript React-触发表行上的单击事件,javascript,reactjs,Javascript,Reactjs,我无法从React中的表行调用click事件。下面是我的代码。我有一个单独的函数来单独填充行,但似乎我把绑定信息弄乱了 import React, {Component, PropTypes} from 'react'; import Header from './Header'; export default class SongData extends Component { constructor(props, context) { super(props, context);

我无法从React中的表行调用click事件。下面是我的代码。我有一个单独的函数来单独填充行,但似乎我把绑定信息弄乱了

import React, {Component, PropTypes} from 'react';
import Header from './Header';

export default class SongData extends Component {
 constructor(props, context) {
    super(props, context);
 }

isEmpty(obj) {
    return Object.keys(obj).length === 0;
}

fetchDetails(song) {
    console.log(song);
}

renderResultRows(data) {
    var self = this;
    return data.map(function(song) {
        return (
            <tr onClick={self.fetchDetails(song)}>
                <td data-title="Song">{song.S_SONG}</td>
                <td data-title="Movie">{song.S_MOVIE}</td>
                <td data-title="Year">{song.S_YEAR}</td>
            </tr>
        );
    }.bind(this));
}

render() {
    return (
        <div id="no-more-tables">
            <table className="table table-hover table-bordered table-striped">
                <thead>
                    <tr>
                        <th>Song</th>
                        <th>Movie</th>
                        <th>Year</th>
                    </tr>
                </thead>
                <tbody>
                    {!this.isEmpty(this.props.searchResult)
                        ? this.renderResultRows(this.props.searchResult)
                        : ''}
                </tbody>
            </table>
        </div>
    );
}
import React,{Component,PropTypes}来自'React';
从“./头”导入头;
导出默认类SongData扩展组件{
构造函数(道具、上下文){
超级(道具、背景);
}
isEmpty(obj){
返回Object.keys(obj).length==0;
}
获取详细信息(歌曲){
console.log(歌曲);
}
renderResultRows(数据){
var self=这个;
返回数据.map(函数(歌曲){
返回(
{song.S_song}
{宋·苏电影}
{宋·苏年}
);
}.约束(这个);
}
render(){
返回(
歌曲
电影
年
{!this.isEmpty(this.props.searchResult)
?this.renderResultRows(this.props.searchResult)
: ''}
);
}

}

首先,您要将经过计算的函数调用传递给您的
onClick
属性

请单独查看以下代码:

 function foo(name) { return 'hello ' + name; }

 foo('bob');
您希望
foo('bob')
的输出是“hellobb”

如果我将它传递到on
onClick
prop,则完全相同。例如:

 <button onClick={foo('bob')}
但这仍然不是最优的。当使用这样的匿名语法(例如,
{console.log('clicked')}
)时,我们在每个渲染上创建一个新函数。如果使用纯组件(即仅当提供新道具实例时才应重新渲染的组件-此检查通过浅层比较执行),则这可能是一个问题。始终尝试尽早创建函数,例如在构造函数中或通过类属性创建函数(如果您使用的是babel stage 1),这样您就可以始终传递相同的引用

但是,对于您的示例,您需要将一个值“传递到”每个
onClick
处理程序中。为此,您可以使用以下方法:

fetchSongDetails = () => {
  const song = e.target.getAttribute('data-item');
  console.log('We need to get the details for ', song);
}

renderResultRows(data) {
    return data.map((song, index) => {  // anon func maintains scope!
        // Pass in a function to our onClick, and make it anon
        // to maintain scope.  The function body can be anything
        // which will be executed on click only.  Our song value
        // is maintained via a closure so it works.
        return (
            <tr key={index} data-item={song} onClick={this.fetchSongDetails}>
                <td data-title="Song">{song.S_SONG}</td>
                <td data-title="Movie">{song.S_MOVIE}</td>
                <td data-title="Year">{song.S_YEAR}</td>
            </tr>
        );
    });  // no need to bind with anon function
}
fetchSongDetails=()=>{
const-song=e.target.getAttribute('data-item');
log('我们需要获得'宋'的详细信息);
}
renderResultRows(数据){
返回数据.map((歌曲,索引)=>{//anon func维护范围!
//将函数传递给我们的onClick,并使其成为onon
//维护作用域。函数体可以是任何内容
//只需点击即可执行。我们的歌曲价值
//通过闭包进行维护,使其正常工作。
返回(
{song.S_song}
{宋·苏电影}
{宋·苏年}
);
});//无需使用anon函数绑定
}
这是一个更好的方法。还要注意,我在生成的每一行中添加了一个
道具。这是另一个react最佳实践,因为react将在其差异化算法中使用唯一的密钥标识符


我强烈推荐以下内容:

  • 范围和闭包:
  • React&ES6/2015
  • 反应和动态子项:
除了@ctrlplusb之外,我想建议另一种在点击事件中传递对象的方法:

//歌曲成分

import React from 'react';
import RowComponent from './RowComponent';

export default class SongData extends React.PureComponent {

  fetchDetails(songObj) {
    // whatever
  }

  renderResultRows(data) {
    return data.map(songObj => (
      <RowComponent
        key={songObj.id}
        data={songObj}
        onClick={this.fetchDetails}
      />;
  }

  render() {

    const { data } = this.props;

    return (
      <div>
        <table>
         <thead>
         </thead>
         <tbody>
          {
            this.renderResultRows(data)
          }
         </tbody>
        </table>
      </div>
    );
  }
}
import React from 'react';

export function RowComponent(props) {
  const { data, onClick } = props;

  function handleClick() {
    onClick(data);
  }

  return (
    <tr onClick={handleClick}>
      <td data-title="Song">{data.S_SONG}</td>
      <td data-title="Movie">{data.S_MOVIE}</td>
      <td data-title="Year">{data.S_YEAR}</td>
    </tr>
  );
}
从“React”导入React;
从“./RowComponent”导入RowComponent;
导出默认类SongData扩展React.PureComponent{
获取详细信息(songObj){
//随便
}
renderResultRows(数据){
返回data.map(songObj=>(
;
}
render(){
const{data}=this.props;
返回(
{
此.renderResultRows(数据)
}
);
}
}
//行组件

import React from 'react';
import RowComponent from './RowComponent';

export default class SongData extends React.PureComponent {

  fetchDetails(songObj) {
    // whatever
  }

  renderResultRows(data) {
    return data.map(songObj => (
      <RowComponent
        key={songObj.id}
        data={songObj}
        onClick={this.fetchDetails}
      />;
  }

  render() {

    const { data } = this.props;

    return (
      <div>
        <table>
         <thead>
         </thead>
         <tbody>
          {
            this.renderResultRows(data)
          }
         </tbody>
        </table>
      </div>
    );
  }
}
import React from 'react';

export function RowComponent(props) {
  const { data, onClick } = props;

  function handleClick() {
    onClick(data);
  }

  return (
    <tr onClick={handleClick}>
      <td data-title="Song">{data.S_SONG}</td>
      <td data-title="Movie">{data.S_MOVIE}</td>
      <td data-title="Year">{data.S_YEAR}</td>
    </tr>
  );
}
从“React”导入React;
导出功能行组件(道具){
const{data,onClick}=props;
函数handleClick(){
onClick(数据);
}
返回(
{data.S_SONG}
{data.S_MOVIE}
{data.S_YEAR}
);
}

使用变量绑定来避免在呈现时调用函数:
self.fetchDetails.bind(song)

您的fetchsongtails()回调中的e.target似乎引用了单击的表单元格,而不是行。使用e.currentTarget可以提供所需的行引用。(顺便说一句,感谢您花时间写出如此全面、简洁和信息丰富的答案。)在函数“fetchSongDetails()”中,您使用:const song=e.target.getAttribute('data-item');但在“fetchSongDetails()”中的“song”变量中,它不会返回真正的“song”对象。您需要“html attribute”“data-item”它将返回无法使用的文本字符串“object object”,而不会返回真正的“song”对象。