reactjs - React Refs กับ TypeScript: ไม่สามารถอ่านคุณสมบัติ 'current' ของ undefined
ฉันกำลังสร้างแอปพลิเคชัน React โดยใช้ TypeScript
ฉันต้องการสร้างปุ่มที่เลื่อนไปยังหัวข้อของคอมโพเนนต์ย่อยบนหน้าหลักของฉัน
ฉันได้สร้างรีฟในคอมโพเนนต์ลูก ตามคำตอบใน Stack Overflow นี้ และ (พยายาม) ใช้ 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 ช่วยฉันสร้าง 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 นี่อาจเกี่ยวข้องกับข้อเท็จจริงที่ว่าในแอปพลิเคชันจริงของฉัน คอมโพเนนต์ลูกถูกห่ออยู่ภายใน withStyle ของ material-ui และ connect ของ React-Redux หรือไม่?
คำตอบ #1
โอเปอเรเตอร์ยืนยันค่าไม่เป็นศูนย์ ! จะปิดกั้นปัญหาที่แท้จริง ใน JavaScript/TypeScript ไม่มีวิธีที่ testTitleRef จะถูกกำหนดจากการใช้งานเป็น <Child ref={this.titleRef} /> ดังนั้นมันจะยังคงเป็น undefined (นอกจากนี้ยังมีความไม่สอดคล้องกันระหว่าง 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 />
}
}
