Почему JavaScript () работает, но цикл for не работает с React? - PullRequest
0 голосов
/ 05 ноября 2018

Я учу себя Реагировать, и я столкнулся с чем-то, что мне трудно понять. Когда я строю свой проект с кодом в getNavList () ниже, я получаю следующую ошибку при нажатии одной из кнопок, отображаемых в моем компоненте, «не может прочитать свойство undefined« click »реагирует».

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, используя сокращенный синтаксис "<> ... </>", но когда я пытаюсь использовать " ... ", я получаю Ошибка в том, что в конце моего оператора else есть ожидаемый символ '}'. Что, черт возьми, это значит?

Пожалуйста, извините и пробелы в моих фрагментах кода и тегах React. Я не мог понять, как заставить их отображаться без добавления дополнительных пробелов, и я почти полностью уверен, что это не синтаксическая ошибка, но не стесняйтесь доказать, что я ошибаюсь, если это так.

1 Ответ

0 голосов
/ 06 ноября 2018

OnClick = {this.props.navButtons [I] .click ()}

При первом взгляде на событие click реагирует на оценку свойства при монтировании компонента. Это заставляет .click() быть вызванным немедленно. Есть два способа это исправить. Один из них - просто снять скобки, чтобы вы не выполняли свой обработчик щелчков сразу .click. Другой вариант заключается в том, чтобы обработчик щелчка возвращал другую функцию (см. Последний пример).

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

Во второй попытке вы передаете анонимный метод, который вызывает ваш .click(). В этом случае реагирует, оценивает значение, которое является функцией, а затем сохраняет его. Затем React будет вызывать эту функцию при срабатывании события.

Бонусные баллы! Иногда вы хотите иметь значение (например, индекс из цикла), которое используется в вашем обработчике кликов. Однако когда вы запускаете событие, оно имеет неправильное значение. Вы можете исправить это, вызвав функцию, которая возвращает функцию. Затем он позволит вам правильно определить это значение, чтобы оно было там, когда вам это нужно.

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

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

То, что происходит в этом примере, это то, что handleClick выполняется при монтировании, кажется, что оно не заключено в функцию. Он принимает индексный номер и затем возвращает другую функцию, которая хранится для этого обработчика кликов. При вызове любого из событий они сохраняют копию значения индекса в своей области видимости, чтобы вы могли иметь к нему доступ.

...