อะไรคือความแตกต่างระหว่าง“ super ()” และ“ super (อุปกรณ์ประกอบฉาก)” ใน React เมื่อใช้คลาส es6


คำตอบ:


709

มีเพียงเหตุผลเดียวที่ต้องผ่านpropsไปsuper():

เมื่อคุณต้องการเข้าถึงthis.propsในตัวสร้าง

ผ่าน:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

ไม่ผ่าน:

class MyComponent extends React.Component {    
    constructor(props) {
        super()

        console.log(this.props)
        // -> undefined

        // Props parameter is still available
        console.log(props)
        // -> { icon: 'home', … }
    }

    render() {
        // No difference outside constructor
        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

โปรดทราบว่าผ่านหรือไม่ผ่านpropsจะsuperมีไม่มีผลกระทบกับการใช้ที่ใหม่กว่าของนอกthis.props constructorนั่นคือrender, shouldComponentUpdateหรือจัดการเหตุการณ์เสมอสามารถเข้าถึงได้

สิ่งนี้ถูกกล่าวอย่างชัดเจนในคำตอบเดียวของ Sophie Alpert สำหรับคำถามที่คล้ายกัน


เอกสาร - รัฐและวงจรชีวิตการเพิ่มสถานะท้องถิ่นลงในคลาสจุดที่ 2 - คำแนะนำ:

ส่วนประกอบคลาสควรเรียกตัวสร้างฐานด้วยpropsเสมอ

อย่างไรก็ตามไม่มีเหตุผลให้ เราสามารถคาดการณ์ว่าเป็นเพราะคลาสย่อยหรือเพื่อความเข้ากันได้ในอนาคต

(ขอบคุณ @MattBrowne สำหรับลิงค์)


16
ฉันคิดว่าคุณถูกต้องแม้จะมีคำตอบอื่น ๆ ที่ให้คะแนนมากกว่านี้ this.propsเป็นเว้นแต่ส่งผ่านไปยังundefined super()ไม่ว่าจะด้วยวิธีใดจะไม่มีผลกับการเรนเดอร์หรือความพร้อมใช้งานthis.propsในrender()ภายหลัง
Micros

3
@Rotareti ไม่จริงเหลือของชั้นไม่ขึ้นอยู่กับโครงสร้างนี้นั่นคือจุด ส่วนประกอบได้รับอุปกรณ์ประกอบฉากด้วยวิธีที่แตกต่างกันโดยพารามิเตอร์ตัวสร้าง และเมื่อคุณส่งอุปกรณ์เริ่มต้นไปที่superคุณมีการอ้างอิงถึงพวกเขาในตัวสร้าง
Robin Pokorny

7
ตามเอกสารตอบสนองคุณก็ควรจะผ่านpropsไปsuper(): facebook.github.io/react/docs/... ฉันไม่แน่ใจว่าทำไมเนื่องจากเมื่อคุณชี้ให้เห็นthis.propsว่าสามารถเข้าถึงได้ในวิธีอื่นทั้งสองวิธี ... บางทีพวกเขาอาจแนะนำสิ่งนี้เพื่อความเข้ากันได้ในอนาคตในกรณีที่ React เวอร์ชันในอนาคตอาจต้องการทำอะไรบางอย่างpropsในคอนสตรัคเตอร์
Matt Browne

23
บางทีฉันแค่เปิดสามารถของเวิร์มที่นี่ แต่ทำไมที่เคยผ่านpropsไปsuperเมื่อเป็นคุณชี้ออกpropsพารามิเตอร์มีสิทธิใช้ได้สำหรับเราที่จะใช้ภายในสร้างและthis.propsใช้งานได้ทุกที่อื่น? มีประโยชน์ที่จะใช้this.propsมากกว่าเพียงแค่props? มันเป็นการปฏิบัติที่ไม่ดีที่จะทำลายโครงสร้างpropsในคอนสตรัคเตอร์หรือไม่? ฉันคิดว่าฉันยังคงล้มเหลวในการดูกรณีเมื่อคุณต้องการที่จะผ่านpropsไปsuperแต่ฉันยินดีที่จะเดิมพันมันเป็นเพียงความไม่รู้ของฉันฮ่า
indiesquidge

9
หากคุณใช้super(props)คุณสามารถเรียกวิธีการที่ใช้this.props ในจากตัวสร้างเช่นthis.doStuffUsingThisDotProps()โดยไม่ต้องส่งผ่านพารามิเตอร์อุปกรณ์ประกอบฉากไปยังวิธีการ / ฟังก์ชั่นเหล่านั้น ฉันเพิ่งเขียนนวกรรมิกที่ทำสิ่งนี้ซึ่งดูเหมือนจะต้องการให้ฉันใช้super(props)ก่อนตามคำตอบของคำถามนี้
Victor Zamanian

54

ในตัวอย่างนี้คุณกำลังขยายReact.Componentคลาสและตามข้อกำหนด ES2015 ตัวสร้างคลาสย่อยไม่สามารถใช้งานได้thisจนกว่าจะsuper()ถูกเรียกใช้ ตัวสร้างคลาส ES2015 ต้องเรียกsuper()ถ้าเป็นคลาสย่อยด้วย

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

ตรงกันข้าม:

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

รายละเอียดเพิ่มเติมตามคำตอบล้นสแต็คที่ยอดเยี่ยมนี้

คุณอาจเห็นตัวอย่างของส่วนประกอบที่สร้างขึ้นโดยการขยายReact.Componentคลาสที่ไม่ได้โทรsuper()แต่คุณจะสังเกตเห็นสิ่งเหล่านี้ไม่มีconstructorดังนั้นจึงไม่จำเป็น

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}

จุดหนึ่งของความสับสนที่ฉันเคยเห็นจากนักพัฒนาบางคนที่ฉันพูดถึงคือส่วนประกอบที่ไม่มีconstructorและดังนั้นจึงไม่โทรไปsuper()ที่ใดก็ได้ยังคงมีthis.propsอยู่ในrender()วิธีการ โปรดจำไว้ว่ากฎนี้และความจำเป็นนี้เพื่อสร้างthisผลผูกพันสำหรับใช้เฉพาะกับconstructorconstructor


15
ขอบคุณมากสำหรับคำตอบของคุณ แต่ไม่ได้ตอบคำถามเดิมของฉัน (ความแตกต่างระหว่างsuper()และsuper(props))
Misha Moroshko

46

เมื่อคุณผ่านpropsไปยังอุปกรณ์ประกอบฉากได้รับมอบหมายให้super thisดูสถานการณ์ต่อไปนี้:

constructor(props) {
    super();
    console.log(this.props) //undefined
}

เมื่อคุณทำเช่นเคย:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}

คำตอบที่ดีที่สุดในรายการ
Basavaraj Hadimani

คำตอบนี้ถูกต้องครึ่งตัวอย่างนี้มีไว้สำหรับวิธีการกำหนดเท่านั้น ตัวอย่างเช่นแม้ว่าคุณจะไม่ได้เขียน super (อุปกรณ์ประกอบฉาก) this.props ภายใต้วิธีการแสดงผลจะยังคงได้รับมอบหมายและพร้อมใช้งาน เหตุผลเดียวที่กล่าวถึงข้างต้นคือเมื่อใช้ this.props ในตัวสร้าง
Ofear

12

ตามรหัสแหล่งที่มา

function ReactComponent(props, context) {
  this.props = props;
  this.context = context;
}

คุณต้องผ่านpropsทุกครั้งที่มีอุปกรณ์ประกอบฉากและคุณจะไม่ใส่มันเข้าไปthis.propsด้วยตนเอง


1
ฉันยังไม่ชัดเจนในเรื่องนี้ หากคุณดูองค์ประกอบทั้งสองนี้คุณจะเห็นสายหนึ่งและอีกสายไม่ได้ แต่ผู้บริโภคของพวกเขาทั้งสองตั้งอุปกรณ์ประกอบฉาก อะไรคือความแตกต่าง? super(props)
Kyeotic

สิ่งนี้หมายความว่าthis.props = propsและsuper(props)เป็นสิ่งเดียวกันหรือไม่
reectrix

1
นี่ไม่เป็นความจริง. ReactElementตั้งค่าthis.propsจาก 'ภายนอก' โดยไม่คำนึงถึงสิ่งที่ทำในตัวสร้าง
Robin Pokorny

11

Dan Abramov เขียนบทความในหัวข้อนี้:

ทำไมเราเขียน super (อุปกรณ์ประกอบฉาก)?

และสิ่งสำคัญของมันคือการมีนิสัยชอบส่งผ่านเพื่อหลีกเลี่ยงสถานการณ์นี้ที่จริงแล้วฉันไม่เห็นว่ามันจะเกิดขึ้นได้:

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); // 😬 We forgot to pass props
    console.log(props);      // ✅ {}
    console.log(this.props); // 😬 undefined 
  }
  // ...
}

8

super() ใช้เพื่อเรียกคอนสตรัคเตอร์หลัก

super(props)จะผ่านpropsไปยังผู้สร้างหลัก

จากตัวอย่างของคุณsuper(props)จะเรียกReact.Componentนวกรรมิกที่ส่งผ่านpropsเป็นอาร์กิวเมนต์

ข้อมูลเพิ่มเติมเกี่ยวกับsuper: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super


18
ใช่นั่นคือสิ่งที่มันทำ แต่ทำไม ? และเมื่อหนึ่งในสองรูปแบบที่จำเป็นในการตอบสนองคืออะไร?
Bergi

7

เมื่อใช้งานconstructor()ฟังก์ชั่นภายในส่วนประกอบ React super()มันเป็นข้อกำหนด โปรดทราบว่าMyComponentองค์ประกอบของคุณกำลังขยายหรือยืมฟังก์ชันการทำงานจากReact.Componentคลาสฐาน

คลาสพื้นฐานนี้มีconstructor()ฟังก์ชั่นของตัวเองที่มีรหัสอยู่ภายในเพื่อติดตั้งส่วนประกอบ React สำหรับเรา

เมื่อเรากำหนดconstructor()ฟังก์ชั่นในMyComponentชั้นเรียนของเราเราเป็นหลักแทนที่หรือแทนที่constructor()ฟังก์ชั่นที่อยู่ในReact.Componentชั้นเรียน แต่เรายังต้องให้แน่ใจว่ารหัสการตั้งค่าทั้งหมดในconstructor()ฟังก์ชั่นนี้ยังคงได้รับการเรียก

ดังนั้นเพื่อให้แน่ใจว่าReact.Componentเป็นฟังก์ชั่นได้รับการเรียกเราเรียกconstructor() คือการอ้างอิงถึงฟังก์ชั่นผู้ปกครองนั่นคือทั้งหมดที่มันเป็นsuper(props)super(props)constructor()

เราต้องเพิ่มsuper(props)ทุกครั้งที่เรากำหนดconstructor()ฟังก์ชั่นภายในองค์ประกอบตามระดับ

super(props)ถ้าเราทำไม่ได้เราจะเห็นข้อผิดพลาดที่บอกว่าเราจะต้องโทร

เหตุผลทั้งหมดสำหรับการกำหนดconstructor()funciton นี้คือการเริ่มต้นวัตถุรัฐของเรา

ดังนั้นเพื่อเริ่มต้นวัตถุสถานะของเราภายใต้การเรียกสุดฉันจะเขียน:

class App extends React.Component {
  constructor(props) {
      super(props);

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};

ดังนั้นเราจึงได้กำหนดของเราconstructor()วิธีการเริ่มต้นวัตถุรัฐของเราโดยการสร้างวัตถุ JavaScript, การกำหนดคุณสมบัติหรือคู่ค่า / this.stateคีย์มันกำหนดผลจากการที่ไป ตอนนี้แน่นอนว่านี่เป็นเพียงตัวอย่างที่นี่ดังนั้นฉันไม่ได้กำหนดคู่ของคีย์ / ค่าให้กับวัตถุสถานะมันเป็นเพียงวัตถุเปล่า


4

นี่คือไวโอลินที่ฉันได้ทำ: jsfiddle.net มันแสดงให้เห็นว่าอุปกรณ์ประกอบฉากได้รับมอบหมายไม่ได้อยู่ในการสร้างโดยค่าเริ่มต้น ตามที่ผมเข้าใจพวกเขาจะ assinged React.createElementในวิธีการ ดังนั้นsuper(props)ควรจะเรียกว่าเฉพาะเมื่อ superclass ของ assings คอนสตรัคด้วยตนเองเพื่อprops this.propsหากคุณเพียงแค่ขยายการReact.Componentโทรsuper(props)จะไม่ทำอะไรกับอุปกรณ์ประกอบฉาก อาจจะมีการเปลี่ยนแปลงใน React เวอร์ชันถัดไป


3

ที่นี่เราจะไม่ได้สิ่งนี้ในนวกรรมิกดังนั้นมันจะกลับมาไม่ได้กำหนด แต่เราจะสามารถดึงสิ่งนี้ออกมานอกฟังก์ชั่นการสร้าง

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error i.e return undefined
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

ถ้าเราใช้ super () เราก็สามารถดึงตัวแปร "this" ภายในนวกรรมิกได้เช่นกัน

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

ดังนั้นเมื่อเราใช้ super (); เราจะสามารถดึงข้อมูลได้ แต่ this.props จะไม่ได้กำหนดไว้ในตัวสร้าง แต่นอกเหนือจากคอนสตรัคเตอร์นี้

ถ้าเราใช้ super (อุปกรณ์ประกอบฉาก) จากนั้นเราสามารถใช้ this.props มูลค่าภายในนวกรรมิกเช่นกัน

คำตอบของ Sophie Alpert

ถ้าคุณต้องการใช้ thisprops ในนวกรรมิกคุณจะต้องผ่านอุปกรณ์ประกอบฉากไปยังสุดยอด มิฉะนั้นจะไม่สำคัญเนื่องจาก React จะตั้งค่า .props ให้กับอินสแตนซ์จากภายนอกทันทีหลังจากเรียกตัวสร้าง


3

สำหรับการตอบสนองเวอร์ชัน 16.6.3 เราใช้super (อุปกรณ์ประกอบฉาก)เพื่อเริ่มต้นชื่อองค์ประกอบของรัฐ: this.props.name

constructor(props){
    super(props);        
}
state = {
  name:this.props.name 
    //otherwise not defined
};
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.