web-dev-qa-db-ja.com

React TypeScriptを使用した参照:未定義のプロパティ 'current'を読み取れません

TypeScriptを使用してReactアプリケーションを構築しています。

メインページの子コンポーネントのヘッダーにスクロールするボタンを作成したいと思います。

このスタックオーバーフロー 回答に続いて、子コンポーネントにrefを作成し、(試行した) forward refs を使用して親コンポーネントでそれにアクセスしました。

_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
_

Refが未定義であることを意味します。何故ですか?私は何が間違っているのですか?

編集:Estus 参照を作成するのに役立ちました。しかし、scrollToTestTitleRef()イベントをトリガーすると、スクロールしません。 _console.log_ _this.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_のキーは循環依存関係が含まれているため、削除しました。

したがって、currentにはoffsetTopのキーがないようです。これは、私の実際のアプリケーションでは、子コンポーネントがマテリアルUIのwithStyleとReact-Reduxのconnectにラップされているという事実と関係があるのでしょうか?

3
J. Hesters

_!_ null以外のアサーション演算子は、実際の問題を抑制します。 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 />
  }
}
_
2
Estus Flask