Реагируйте ссылками с TypeScript: невозможно прочитать свойство 'current' из undefined

Я строю приложение React с использованием TypeScript.

Я хочу создать кнопку, которая прокручивает заголовок дочернего компонента на моей главной странице.

Я создал ссылку в дочернем компоненте, следуя этому ответу о переполнении стека, и (пытался) использовать прямые ссылки для доступа к нему в моем родительском компоненте.

export class Parent extends Component {
  private testTitleRef!: RefObject<HTMLHeadingElement>;

  scrollToTestTitleRef = () => {
    if (this.testTitleRef.current !== null) {
      window.scrollTo({
        behavior: "smooth",
        top: this.testTitleRef.current.offsetTop
      });
    }
  };

  render() {
    return <Child ref={this.testTitleRef} />
  }
}

interface Props {
  ref: RefObject<HTMLHeadingElement>;
}

export class Child extends Component<Props> {
  render() {
    return <h1 ref={this.props.ref}>Header<h1 />
  }
}

К сожалению, когда я запускаю scrollToTestTitleRef Я получаю ошибку:

Cannot read property 'current' of undefined

Это означает, что ссылка не определена. Это почему? Что я делаю неправильно?

РЕДАКТИРОВАТЬ: estus помог мне создать ссылку. Но когда я вызываю scrollToTestTitleRef() событие, оно не прокручивается. Когда я console.logthis.testTitleRef.current Я получаю вывод:

{"props":{},"context":{},"refs":{},"updater":{},"jss":{"id":1,"version":"9.8.7","plugins":{"hooks":{"onCreateRule":[null,null,null,null,null,null,null,null,null,null,null,null],"onProcessRule":[null,null,null],"onProcessStyle":[null,null,null,null,null,null],"onProcessSheet":[],"onChangeValue":[null,null,null],"onUpdate":[null]}},"options":{"plugins":[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]}},"sheetsManager":{},"unsubscribeId":null,"stylesCreatorSaved":{"options":{"index":-99999999945},"themingEnabled":false},"sheetOptions":{},"theme":{},"_reactInternalInstance":{},"__reactInternalMemoizedUnmaskedChildContext":{"store":{},"storeSubscription":null},"state":null}

Примечание: я удалил ключи cacheClasses, _reactInternalFiber а также __reactInternalMemoizedMaskedChildContext потому что они содержали циклические зависимости.

Таким образом, ток не имеет ключа offsetTop, Может быть, это как-то связано с тем, что в моем реальном приложении дочерний компонент обернут внутри материала-интерфейса пользователя? withStyle и Реакт-Редукс connect?

1 ответ

Решение

! ненулевой оператор утверждения подавляет актуальную проблему. В JavaScript/TypeScript нет способа, как testTitleRef свойство может быть назначено из использования в качестве <Child ref={this.titleRef} />так что он остается неопределенным (есть также несоответствие с testTitleRef а также titleRef).

Это должно быть что-то вроде:

  private testTitleRef: React.createRef<HTMLHeadingElement>();

  scrollToTestTitleRef = () => {
      if (!this.testTitleRef.current) return;

      window.scrollTo({
        behavior: "smooth",
        top: this.testTitleRef.current.getBoundingClientRect().top + window.scrollY
      });
  };
  render() {
    return <Child scrollRef={this.testTitleRef} />
  }

а также

export class Child extends Component<Props> {
  render() {
    return <h1 ref={this.props.scrollRef}>Header<h1 />
  }
}
Другие вопросы по тегам