ตอบสนอง useContext ด้วย“ setState”

Aug 20 2020

ฉันเพิ่งเริ่มใช้ Context React Api กับ useContext Hook ฉันสังเกตเห็นว่าเมื่อเรามีตัวแปรสถานะเช่น const someState = useState (state, setState) นักพัฒนาบางคนส่ง setSate โดยตรงในค่าผู้ให้บริการแล้วเรียกมันในองค์ประกอบลูก เป็นแนวทางปฏิบัติที่ดีหรือไม่?

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

การผ่าน setState ในบริบทเป็นการสรรเสริญที่ดีหรือไม่? ฉันยังคงมีข้อสงสัยเนื่องจากโดยปกติคุณไม่สามารถส่ง setState ไปยังส่วนประกอบได้โดยตรง มีความแตกต่างในประสิทธิภาพหรือข้อเสียอื่น ๆ ที่ฉันควรพิจารณาหรือไม่?

ขอขอบคุณ.

คำตอบ

2 Amel Aug 20 2020 at 16:40

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

1 Reductio Aug 20 2020 at 16:52

แก้ไข: จริงๆแล้วฉันคิดว่าคุณคิดผิด แต่ฉันไม่แน่ใจ คำตอบของฉันใช้ได้สำหรับกรณีนี้หากคุณเขียนผู้ให้บริการของคุณเองที่มีสถานะ หากคุณใช้ผู้ให้บริการเริ่มต้นที่มีตัวตั้งค่าฉันจะเห็นด้วยกับคำตอบของ Amel


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

แง่บวกของการทำเช่นนี้คือตัวตั้งค่าสถานะที่กำหนดโดย useState จะยังคงเหมือนเดิมสำหรับการเรนเดอร์แต่ละครั้ง หากคุณส่งผ่านค่าที่กำหนดเองคุณควรหลีกเลี่ยงการเปลี่ยนแปลงบ่อยเกินไปเนื่องจากทุกองค์ประกอบที่รับฟังการเปลี่ยนแปลงโดยใช้ useContext จะแสดงผล

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

อะไรทำนองนี้ (ตัวอย่างที่เรียบง่ายมากแน่นอนว่าไม่สมเหตุสมผลเช่นนี้มันเป็นเพียงเพื่อความเข้าใจ):

function MyProvider({children}) {
   const [state, setState] = useState(0);
   const provided = useMemo(() => ({
       value: state,
       setValue: (value) => setState(value)
   }, [value]);
   return <MyContext.Provider value={provided}>{children}</MyContext.Provider>;
}

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