React Refs with TypeScript:无法读取未定义的 属性 'current'
React Refs with TypeScript: Cannot read property 'current' of undefined
我正在使用 TypeScript 构建 React 应用程序。
我想创建按钮,滚动到我主页上 child 组件的 header。
我在 child 组件中创建了一个引用,然后 answer and (tried to) use forward refs 在我的 parent 组件上访问它。
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
的key。这可能与以下事实有关:在我的实际应用程序中,child 组件被包裹在 material-ui 的 withStyle
和 React-Redux' connect
中?
!
非空断言运算符抑制了实际问题。在 JavaScript/TypeScript 中无法将 testTitleRef
属性 分配为 <Child ref={this.titleRef} />
,因此它保持未定义(与 testTitleRef
和 [ 也存在不一致=16=]).
应该是这样的:
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 />
}
}
我正在使用 TypeScript 构建 React 应用程序。
我想创建按钮,滚动到我主页上 child 组件的 header。
我在 child 组件中创建了一个引用,然后
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
的key。这可能与以下事实有关:在我的实际应用程序中,child 组件被包裹在 material-ui 的 withStyle
和 React-Redux' connect
中?
!
非空断言运算符抑制了实际问题。在 JavaScript/TypeScript 中无法将 testTitleRef
属性 分配为 <Child ref={this.titleRef} />
,因此它保持未定义(与 testTitleRef
和 [ 也存在不一致=16=]).
应该是这样的:
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 />
}
}