Получите компонент привязки, отреагировав ref, и обновите его поле href

У меня есть код реакции, в котором есть компонент «<a>». Когда я нажимаю «<a>», я хочу изменить его поле href. Для этого у меня есть «ref», чтобы получить компонент внутри метода «onclick» следующим образом:

      class SomeComponent {
    public ref: React.RefObject<any>;

    constructor(props: any) {
        super(props);
        this.ref = React.createRef();
    }

    render() {
        <a
          href="#"
          ref={ this.ref }
          onClick={this.clicked()}
        />
    } 

    private clicked() {
        const link = this.ref.current;
        link.href = "some_link"; // This doesn't have any effect on the "a" element
    }
}

Но в результате "href" не обновляется. После щелчка также остается "#". Есть идеи, как заставить его работать?

2 ответа

В опубликованном вами коде много опечаток или ошибок:

  • Отсутствующий extends React.Component.
  • Отсутствующий return в .
  • Звонок this.clicked() вместо передачи функции в onClick.
  • Не проверяя это link не null перед назначением на него.
  • Не вызывать событие щелчка, чтобы предотвратить повторную отрисовку до «#».

Вы можете исправить все эти ошибки, и в основном это сработает, но если компонент по какой-либо причине повторно отрендерит, то он вернется, потому что это то, что установлено в render().

      class SomeComponent extends React.Component {
  public ref: React.RefObject<HTMLAnchorElement>;

  constructor(props: {}) {
    super(props);
    this.ref = React.createRef();
  }

  render() {
    return (
      <a href="#" ref={this.ref} onClick={this.clicked}>
        Anchor Text
      </a>
    );
  }

  private clicked = (e: React.MouseEvent) => {
    const link = this.ref.current;
    if (link && link.href === "#" ) {
      e.preventDefault();
      link.href = "some_link";
    }
  };
}

Просто используйте состояние

Нет никакого смысла изменять сквозные манипуляции с DOM, когда вы в первую очередь устанавливаете. Сохранить текущее значение в this.state и отобразите вашу ссылку с помощью href={this.state.href}.

Нам еще нужно условно позвонить e.preventDefault() только тогда, когда href является "#"так что это все еще странный дизайн, который можно улучшить. Может показать div пока не щелкнет aпосле? Но в соответствии с вашими требованиями это будет работать:

      class SomeComponent extends React.Component<{}, { href: string }> {
  constructor(props: {}) {
    super(props);
    this.state = {
      href: "#"
    };
  }

  render() {
    return (
      <a href={this.state.href} onClick={this.clicked}>
        Anchor Text
      </a>
    );
  }

  private clicked = (e: React.MouseEvent) => {
    if ( this.state.href === "#" ) {
      e.preventDefault();
      this.setState({ href: "some_link" });
    }
  };
}

Вам нужно добавить привязку метода внутри конструктора следующим образом:

      constructor(props: any) {
    super(props);
    this.ref = React.createRef();
    this.clicked = this.clicked.bind(this);
}

А затем передайте этот метод компоненту в качестве обратного вызова, например:

      <a
    href="#"
    ref={ this.ref }
    onClick={this.clicked}
  />
Другие вопросы по тегам