เหตุใดเอกสาร React จึงแนะนำให้ทำ AJAX ใน componentDidMount ไม่ใช่ componentWillMount


102

ชื่อเรื่องบอกทุกอย่าง ฉันเข้าใจว่าเหตุใดจึงcomponentDidMountเหมาะสมสำหรับทุกสิ่งที่ต้องการการเข้าถึง DOM แต่คำขอ AJAX ไม่จำเป็นหรือมักจะต้องการสิ่งนี้

สิ่งที่ช่วยให้?


@FurkanO ฉันคิดว่าเขาหมายถึงการเข้าถึงองค์ประกอบ DOM ที่แสดงโดยส่วนประกอบ และเขาพูดถูกทั้งหมดเพราะถ้าคุณพยายามเข้าถึงองค์ประกอบดังกล่าวในcomponentWillMountนั้นจะล้มเหลวเนื่องจากส่วนประกอบนั้น ...
ZekeDroid

@AlanH. ลบคำถามของฉันแน่นอนคุณสามารถเข้าถึง dom บน componentDidMount นี่เป็นกฎไม่มีอะไรจะอธิบายเกี่ยวกับเรื่องนี้ ขอบคุณ.
FurkanO

ในความคิดของฉันคือสาเหตุที่เราเรียกฟังก์ชัน Ajax หลังจาก componentDidMount คือเราต้องตรวจสอบให้แน่ใจก่อนว่า Element นั้นแสดงผลได้อย่างราบรื่นในตอนเริ่มต้น หลังจากนั้นเราสามารถโทร ajax หากเราโทรหา ajax ก่อนและมีข้อผิดพลาดเกิดขึ้นจะทำให้เกิดปัญหาในการเรนเดอร์
Faris Rayhan

คำตอบ:


62

componentDidMountมีไว้สำหรับผลข้างเคียง การเพิ่มผู้ฟังเหตุการณ์ AJAX การกลายพันธุ์ DOM ฯลฯ

componentWillMountไม่ค่อยมีประโยชน์ โดยเฉพาะอย่างยิ่งหากคุณสนใจเกี่ยวกับการแสดงผลฝั่งเซิร์ฟเวอร์ (การเพิ่มตัวฟังเหตุการณ์ทำให้เกิดข้อผิดพลาดและการรั่วไหลและสิ่งอื่น ๆ อีกมากมายที่อาจผิดพลาดได้)

มีการพูดคุยเกี่ยวกับการลบออกcomponentWillMountจากส่วนประกอบของคลาสเนื่องจากมีจุดประสงค์เดียวกับตัวสร้าง มันจะยังคงอยู่บนcreateClassส่วนประกอบ


1
การเพิ่มตัวฟังเหตุการณ์ทำให้เกิดข้อผิดพลาดและรั่วไหลตลอดเวลาบนเซิร์ฟเวอร์หรือเพียงแค่componentWillMount? ฉันไม่เห็นความแตกต่างจริงๆ
Alan H.

18
@Alan - หากคุณใช้ React ทั้งบนฝั่งไคลเอนต์และฝั่งเซิร์ฟเวอร์คุณจะพบว่าทุกสิ่งที่อยู่ภายในcomponentWillMountจะถูกดำเนินการบนการแสดงผลบนเซิร์ฟเวอร์ หากคุณกำลังใช้งานcomponentDidMountนั้นจะถูกดำเนินการบนไคลเอนต์เท่านั้น ด้วยเหตุนี้การใส่สิ่งต่างๆในcomponentWillMountการโต้ตอบภายนอกหรือเชื่อมโยงกับเหตุการณ์ ฯลฯ จึงไม่ใช่ความคิดที่ดี หากคุณไม่มีแผนที่จะแสดงผลส่วนประกอบของคุณบนเซิร์ฟเวอร์ก็ยังไม่ใช่ความคิดที่ดีสำหรับการพกพาโค้ดเท่านั้น ทั้งหมดนี้อยู่นอกเหตุผลหลักที่มันไม่ดีซึ่งอธิบายไว้ในคำตอบของ @daniula
Mike Driver

3
componentWillMount รันบนเซิร์ฟเวอร์ แต่ componentWillUnmount (ที่คุณลบตัวฟัง) ไม่อยู่ สิ่งนี้จะทำให้คุณเพิ่มผู้ฟังและไม่ต้องทำความสะอาด
Brigand

คนในทีม React core กำลังพิจารณาที่จะลบ componentWillMount ออกจากเวอร์ชันในอนาคต
cchamberlain

1
@AnkitSinghaniya มันจะทำลายการแสดงผลเซิร์ฟเวอร์และการทดสอบหน่วยตื้น
Brigand

36

ฉันมีปัญหาเดียวกันในตอนแรกด้วย ฉันตัดสินใจที่จะลองทำตามคำขอcomponentWillMountแต่สุดท้ายเกิดปัญหาเล็ก ๆ น้อย ๆ

ฉันทริกเกอร์การเรนเดอร์เมื่อการโทรของ ajax เสร็จสิ้นด้วยข้อมูลใหม่ ในบางจุดการเรนเดอร์คอมโพเนนต์ใช้เวลามากกว่าการตอบสนองจากเซิร์ฟเวอร์และเมื่อถึงจุดนี้การโทรกลับของ ajax จะทำให้เกิดการเรนเดอร์บนคอมโพเนนต์ที่ไม่ได้ต่อเชื่อม นี้เป็นชนิดของกรณีขอบ componentDidMountแต่อาจมีมากขึ้นดังนั้นจึงปลอดภัยในการติด


โอเคขอบคุณ. คิดว่ามันอาจจะเป็นแบบนั้น แต่คุณพูดถูกมันน่าแปลกใจที่คำขอของ ajax จะเสร็จสิ้นก่อนที่จะแสดงผล
Alan H.

1
@daniula แน่ใจเหรอ? คำขอ AJAX จะเสร็จสิ้นก่อนแสดงผลได้อย่างไร
Leon Grapenthin

4
นี่คือโลกอะซิงโครนัสของเบราว์เซอร์ คุณไม่ควรคิดว่าฟังก์ชันหนึ่งจะเร็วกว่าเสมอไป ดังที่ฉันได้กล่าวไปแล้วว่าเป็นกรณีขอบและอาจหมายความว่าคุณควรเพิ่มประสิทธิภาพกระบวนการเรนเดอร์ของคุณ แต่การใช้วิธีวงจรชีวิตที่เหมาะสมจะทำให้ชีวิตของคุณง่ายขึ้นมาก
daniula

1
ตัวสร้างคลาส @SooChengKoh ES6 เทียบเท่าcomponentWillMountดังนั้นคุณควรใช้componentDidMountสำหรับการโทร ajax ของคุณต่อไป
daniula

1
@SooChengKoh - ไม่ควรทำอะไรในตัวสร้างที่จะนำไปสู่สถานะที่ต้องตั้งค่าซึ่งจะนำไปสู่เงื่อนไขการแข่งขันบนไคลเอนต์และเซิร์ฟเวอร์ คุณไม่ควรเรียกsetStateใช้ตัวสร้างคอมโพเนนต์และคุณไม่มีทางกำหนดได้ว่าการเรียก AJAX จะเสร็จสมบูรณ์เมื่อใด twitter.com/dan_abramov/status/576453138598723585
cchamberlain

3

ตามเอกสารการตั้งค่าสถานะในcomponentWillMountจะไม่ทำให้เกิดการเรนเดอร์ หากการเรียก AJAX ไม่ได้ปิดกั้นและคุณส่งคืนสถานะPromiseที่อัปเดตของคอมโพเนนต์สำเร็จมีโอกาสที่การตอบกลับจะมาถึงเมื่อคอมโพเนนต์ถูกแสดงผล เนื่องจากcomponentWillMountไม่ได้ทริกเกอร์การเรนเดอร์ซ้ำคุณจะไม่มีพฤติกรรมที่คุณคาดหวังซึ่งเป็นส่วนประกอบที่แสดงผลด้วยข้อมูลที่ร้องขอ

หากคุณใช้ไลบรารีฟลักซ์ใด ๆ และข้อมูลที่ร้องขอลงท้ายด้วยการจัดเก็บส่วนประกอบนั้นเชื่อมต่อ (หรือสืบทอดจากส่วนประกอบที่เชื่อมต่อ) สิ่งนี้จะไม่เป็นปัญหาเนื่องจากการรับข้อมูลนั้นส่วนใหญ่จะเปลี่ยนอุปกรณ์ประกอบฉาก ในที่สุด.


1
componentWillMountไม่ทริกเกอร์การเรนเดอร์ซ้ำเพียงเพราะมีการกำหนดสถานะใหม่ก่อนการเรนเดอร์ครั้งแรก แต่ถ้าsetStateถูกเรียกในการเรียกกลับแบบ AJAX จะถูกเรียกอย่างแน่นอนที่สุดหลังจากการเรนเดอร์ครั้งแรกและจะทำให้เกิดการเรนเดอร์ใหม่
webdif
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.