reactjs - 使用 TypeScript 反应 Refs:无法读取未定义的属性“当前”
问题描述
我正在使用 TypeScript 构建一个 React 应用程序。
我想创建一个按钮,它滚动到我主页上子组件的标题。
我在子组件中创建了一个引用,遵循这个堆栈溢出答案并(试图)使用前向引用在我的父组件上访问它。
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 是未定义的。这是为什么?我究竟做错了什么?
编辑:
埃斯图斯帮助我创建了裁判。但是当我触发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
. 这可能与在我的实际应用程序中子组件包装在 material-ui'swithStyle
和 React-Redux'中的事实有关connect
吗?
解决方案
!
非空断言运算符抑制了实际问题。在 JavaScript/TypeScript 中,testTitleRef
无法从 as 分配属性<Child ref={this.titleRef} />
,因此它保持未定义(也与testTitleRef
and不一致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 />
}
}
推荐阅读
- c++ - 奇怪的重载 = 某本书上的运算符,c 风格?
- sql - 在 SQL 表中查找所有两列重复项,其中第三列的后面值大于前面的值
- c# - 理解 Func 的 C# 方法
, 字符串> - python - Pandas/Python:使用 .replace() 从另一列值替换列值
- android - Touch event.getAction 在android studio中的服务类下不起作用
- python - 如何将 pygame.image.save 输出到变量而不是文件?
- python - REST API 忽略 Firebase 存储规则
- ios - 如何使用 Alamofire 关闭证书验证?
- python - PyQt5 - setStyleSheet 透明/alpha 不起作用?
- c# - 在 EF Core 中使用不同的名称指定关系