0

我正在自学 React,但我遇到了一些我无法理解的东西。当我使用下面的 getNavList() 中的代码构建项目时,单击组件中呈现的按钮之一时出现以下错误,“无法读取未定义的‘点击’反应的属性。”

export class Pane extends React.Component {
  constructor(props) {
    super(props);

  }

  getNavList() {
    var buttons = [];
    if(this.props.subNavButtons != null){
      for(var i = 0; i < this.props.navButtons.length; i++) {
        buttons.push(<Button onClick={this.props.navButtons[i].click()} title={this.props.navButtons[i].title} />);
        buttons.push(<Button onClick={this.props.navButtons[i + i].click()} title={this.props.navButtons[i + i].title} />);
        buttons.push(<Button onClick={this.props.navButtons[i + i + 1].click()} title={this.props.navButtons[i + i + 1].title} />);
      }
    } else {
      buttons = this.props.navButtons.map(button => (<Button onClick={() => button.click()} title={button.title}/>));
    }
    return buttons;
  }

  render() {
    return (
      <div>
        <ul>
          {this.getNavList()}
        </ul>
      </div>
    );
  }
}

当我通过以下更改构建项目时,一切都按预期工作:

export class Pane extends React.Component {
      constructor(props) {
        super(props);

      }

      getNavList() {
        var buttons = [];
        if(this.props.subNavButtons != null){
          buttons = this.props.navButtons.map((button, index) => (<>
                                                                  <Button onClick={() => button.click()} title={button.title}/>
                                                                  <Button onClick={() => this.props.subNavButtons[index + index].click()} title={this.props.subNavButtons[index + index].title}/>
                                                                  <Button onClick={() => this.props.subNavButtons[index + index + 1].click()} title={this.props.subNavButtons[index + index + 1].title}/>
                                                                  </>));
        }
        else {
          buttons = this.props.navButtons.map(button => (<Button onClick={() => button.click()} title={button.title}/>));
        }
        return buttons;
      }

      render() {
        return (
          <div>
            <ul>
              {this.getNavList()}
            </ul>
          </div>
        );
      }
    }

从我能够找到的情况来看,当我将函数作为组件属性传递时,“this”似乎会丢失它的上下文。我尝试在其父类中绑定传递给 Pane 对象的函数,但无济于事。我还尝试使用箭头符号定义函数,但没有成功。话虽如此,为什么从 for 循环到 map 函数的这种变化有效?

这是同一代码段中的一个更小问题。使用工作 getNavList() 我使用速记语法“< >...< />”返回一个 React.Fragment,但是当我尝试使用“<React.Fragment>...< /React.Fragment>”时,我得到一个错误说在我的 else 语句末尾有一个预期的 '}' 字符。这到底是怎么回事?

请原谅我的代码片段和 React 标签中的错误。我无法弄清楚如何在不添加额外空格的情况下让它们显示,我几乎完全确定这不是语法错误,但如果是这种情况,请随时证明我错了。

4

1 回答 1

0

onClick={this.props.navButtons[i].click()}

在您第一次点击事件时,react 在安装组件时评估属性。这会导致.click()立即被调用。有两种方法可以解决此问题。一种方法是去掉括号,这样您就不会立即执行您的点击处理程序.click。另一种选择是让点击处理程序返回另一个函数(参见最后一个示例)。

onClick={() => button.click()} title={button.title}

在您的第二次尝试中,您传入一个匿名方法,该方法调用您的.click(). 在这种情况下,react 会评估作为函数的值,然后保存它。当事件被触发时,React 会调用这个函数。

奖励积分!有时您希望在单击处理程序中使用一个值(例如循环中的索引)。但是,当您触发事件时,它的值错误。您可以通过调用返回函数的函数来解决此问题。然后,它将允许您正确地确定该值的范围,以便在您需要时出现。

myThings.map((x, i) => <thing onClick={this.handleClick(i)} />

handleClick = (index: number) => () => {
   alert(index);
}

在这个例子中发生的事情是 handleClick 在挂载时执行似乎它没有被包装在一个函数中。它接受索引号,然后返回为该单击处理程序存储的另一个函数。当任何事件被调用时,它们会在其范围内保留索引值的副本,以便您可以访问它。

于 2018-11-05T21:17:11.850 回答