【问题标题】:Why does JavaScript's map() work but my for loop fails with React?为什么 JavaScript 的 map() 可以工作,但我的 for 循环在 React 中失败?
【发布时间】:2019-04-09 06:13:44
【问题描述】:

我正在自学 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 函数的这种变化有效?

这是同一代码 sn-p 中的一个更小问题。使用有效的 getNavList() 我使用速记语法“...”返回一个 React.Fragment,但是当我尝试使用“...”时,我得到一个错误说在我的 else 语句末尾有一个预期的 '}' 字符。这是什么鬼?

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

【问题讨论】:

    标签: javascript arrays reactjs this react-fullstack


    【解决方案1】:

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

    【讨论】:

    • 谢谢!。这是有道理的,似乎是我所缺少的。一旦我有机会测试它以确保我理解所有内容,我会接受你的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 2015-07-11
    • 2021-11-02
    • 2018-10-11
    • 2020-09-05
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多