【问题标题】:List generated in constructor not calling event handler构造函数中生成的列表未调用事件处理程序
【发布时间】:2018-12-14 09:59:50
【问题描述】:

我在构造函数中生成一个元素列表,并在渲染函数中渲染它。我将this 正确绑定到事件处理程序,但仍然无法调用事件处理程序。我创建了一个codepen

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App boxes="9" />, document.getElementById('root'));

App.js

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

import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.play = this.click.bind(this);
    this.boxes = [];
    for (let i = 0; i < props.boxes; i++) {
      this.boxes.push(<Box key={i} onClick={this.play} />);
    }
  }
  click() {
    console.log('called click');
  }
  render() {
    return <div className="App">{this.boxes}</div>;
  }
}

export default App;

但是,如果我在渲染函数中绑定 onClick 函数,或者即使我在 Box.js 中调用 onClick 属性,它也可以正常工作

Box.js

import React, { Component } from 'react';
import './Box.css';

class App extends Component {
  render() {
    return <div className="box">{this.props.display}</div>;
    // return (
    // <div onClick={this.props.onClick} className="box">
   //   {this.props.display}
   // </div>
   // );  -- this helps me trigger the event handler on App component

  }
}

export default App;

你能帮我添加事件处理程序而不指定两次 onclick 处理程序,即在 App 组件和 Box 组件上

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    你能帮我在不指定 onclick 的情况下添加事件处理程序吗 处理程序两次,即在 App 组件和 Box 组件上

    您必须指定两次,一次是将函数交给 Box 组件,第二次是让 Box 组件决定 何时调用该函数;这是您在第二个示例中所做的,已被注释掉。

    否则,你怎么想象它只指定一次?

    【讨论】:

    • 我想,它会像其他组件一样调用事件处理程序,例如:&lt;div onClick={this.play} className="App"&gt;{this.boxes}&lt;/div&gt;; 这有效
    • @NaeemShaikh 对不起,我不明白这个问题
    • 对不起,我在想如果我从 App 组件创建一个 Box 组件,那么我可以从父 App 传递一个事件处理程序,而无需在子 Box 组件中指定它两次..
    • @NaeemShaikh 抱歉,我很难理解您对什么感兴趣,也许可以更新问题,使其更具体。就像我说的,你必须为 Box 组件赋予函数,而在 Box 组件内部,你必须决定何时调用该函数,对吧?
    • 是的,但我理解你的回答,我认为你是对的,它必须在子组件中控制......谢谢
    【解决方案2】:

    我建议在状态中存储框并在渲染方法中引用onClick,而不是在构造函数中。 顺便说一句,您可以完全摆脱构造函数,只需使用箭头函数作为方法。

    const Box = ({onClick, label}) => (
      <div onClick={onClick}>{label}</div>
    )
    
    class App extends React.Component {
      state = {
        boxes: [
          {id: 1, label: 'Box label 1'},
          {id: 2, label: 'Box label 2'},
        ]
      }
      
      handleClick = () => {
        console.log('box click');
      }
      
      render() {
        const { boxes } = this.state;
        return (
          <div className="App">
            {boxes.map(box => (
              <Box key={box.id} label={box.label} onClick={this.handleClick} />))}
          </div>
        )
      }
    }
    
    
    ReactDOM.render(<App />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      猜你喜欢
      • 2016-09-06
      • 2013-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多