【问题标题】:div's id attribute is undefined/not getting captured onClick in a react appdiv 的 id 属性未定义/未在反应应用程序中捕获 onClick
【发布时间】:2018-03-20 09:38:20
【问题描述】:

我正在映射来自 api 响应的数据并从中渲染多个 div。除此之外,我将响应中的唯一 id 分配给每个 div 的 id 属性,如下所示:

...lists.map(list => {
  return (
  <div className='one' key={list.id} id={list.id} onClick={this.handleClick}>
    <div className='two'>
      <p>Hello World</p>
      <span>Foo Bar</span>
    </div>
  </div>
)
})

handleClick = (e) => {
  console.log(e.target.id)
  // other stuff
}

问题:

每当单击外部 div (className='one') 时,控制台日志未定义。但是,如果我将 id 值分配给内部 div (className='two'),它只会记录 id 的值只有在内部 div 的维度内进行点击&lt;span&gt;&lt;p&gt; 标签也是如此。

基本上,onClick 在点击不同的 html 元素时返回不同的目标。

预期结果:

单击父 div 或该 div 内的任何位置应始终返回父 div 的 id 属性值。

【问题讨论】:

    标签: javascript html reactjs


    【解决方案1】:

    尝试将事件设置为函数参数

    handleClick = (e) => {
      console.log(e.target.id)
      // other stuff
    }
    

    【讨论】:

    • 我的代码中已经有这个了,只是没有把它放在问题中。
    【解决方案2】:

    如果你已经在使用 ES6

    我会稍微修改一下代码,这样会更容易理解和使用events 目标和属性不会出现特殊故障

    lists.map(list => {
        return (
           <div 
               className='one' 
               key={list.id} 
               onClick={this.handleClick.bind(this, list.id)
    
               <div className='two'>
                 <p>Hello World</p>
                 <span>Foo Bar</span>
               </div>
           </div>
        )
     })
    
     handleClick = (listId) => {
       console.log(listId)
       // other stuff
     }
    

    正如你在这里看到的,我只是用列表 id 调用方法就完成了

    【讨论】:

    • 匿名函数会一直导致重新渲染,因为每次渲染这个组件时它都会返回一个新的引用
    • @JoseAPL 现在我删除了匿名函数。没有理由因此而否决它。但现在它不会重新渲染
    • this.handleClick.bind 也会产生同样的效果,因为你正在绑定一个新的引用,它必须是一个内部函数绑定一次,我这样做是因为这会导致 React 项目的性能问题!
    • 你不应该这样做,因为 bind 每次都会返回一个新函数。看到这个问题stackoverflow.com/questions/45053622/…
    【解决方案3】:

    在构造函数中,只需输入这一行:

    constructor() {
         this.handleClick = this.handleClick.bind(this);
    }
    

    在此之后,您将能够访问该元素的 ref,

    更多详情请浏览此链接: https://reactjs.org/docs/handling-events.html

    【讨论】:

      【解决方案4】:

      问题是当您在 topMost 父级上定义 onClick 时,您需要使用 e.currentTarget.id 而不是 e.target.id,因为 e.target 会给您您单击的元素,而不是您单击的父级onClick 监听器已定义

      class App extends React.Component {
      state = {
        lists: [{id: 1}, {id: 2}, {id:3}]
      }
      render() {
        return (
          <div>
            {this.state.lists.map(list => {
                console.log(list.id)
                return (
                <div className='one' key={list.id} id={list.id} onClick={this.handleClick}>
                  <div className='two'>
                    <p>Hello World</p>
                    <span>Foo Bar</span>
                  </div>
                </div>
              )
             })
             }
          </div>
        )
      }
      
      handleClick = (e) => {
        console.log(e.currentTarget.id)
        
        // other stuff
      }
      
      }
      
      ReactDOM.render(<App/>, document.getElementById('app'));
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
      <div id="app"></div>

      【讨论】:

      • 感谢 Shubham,正是我想要的。
      • 也看看这个答案,它可以帮助stackoverflow.com/questions/45053622/…
      • 经历了这一切,我认为这将是正确处理此问题的最佳解决方案。创建一个单独的组件并将 id 作为 props 传递不仅是一种更清洁而且是一种有效的解决方案。
      【解决方案5】:

      好的,问题不在于 Reactjs,问题在于事件目标。

      当您必须使用event.currentTarget 时,您使用的是e.target,这就是区别。

      • target 是触发事件的元素(例如,用户点击)
      • currentTarget 是事件监听器附加到的元素。

      让我们看一个例子:

      let tacos = [{
       	person: "John",
        ingredient: 'Guacamole'
       }, {
       	person: 'Sally',
        ingredient: 'Beef'
       }];
      
      class App extends React.Component {
      
        render() {
          return (
            <div>
              <h3>List of tacos:</h3>
              <TacosList tacos={tacos} />
            </div>
          );
        }
      }
      
      class TacosList extends React.Component {
      	constructor(props) {
        	super(props);
      
          this.handleClick = this.handleClick.bind(this);
        }
      	
        handleClick(event) {
        	const currentTarget = event.currentTarget;
          
          console.log(event.target);
          console.log(currentTarget.id);
        }
        
        render() {
          return (
            <div>
              {this.props.tacos.map((taco, index) => (
      					<div className="one" id={`reference-${index}`} key={index} onClick={this.handleClick}>
                	<p>{taco.person}: {taco.ingredient}</p>					  
      					</div>
              ))}
            </div>
          );
        }
      }
      
      ReactDOM.render(<App />, document.getElementById("root"));
      .one {
        padding: 20px;
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
      <div id="root">
      </div>

      请注意,您可以单击 divp 元素,两者都会触发事件,在 p 的情况下,它会将事件传播到 div ,因此,它是事件的时间目标变化

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-08
        • 1970-01-01
        • 2019-12-07
        • 2013-07-23
        • 2018-11-09
        相关资源
        最近更新 更多