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
にラップされているという事実と関係があるのでしょうか?
_!
_ 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 />
}
}
_