ค้นหาเว็บไซต์

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 />
  }
}

บทความที่เกี่ยวข้อง