React.useState ไม่รีโหลดสถานะจากอุปกรณ์ประกอบฉาก


95

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

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

codepen

คำตอบ:


210

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

หากคุณต้องการอัปเดตสถานะเกี่ยวกับการเปลี่ยนแปลงเสาให้ใช้useEffecthook

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

การสาธิตการทำงาน


18
เมื่อตั้งค่าสถานะเริ่มต้นในตัวสร้างมันชัดเจนที่จะเข้าใจว่าตัวสร้างถูกเรียกหนึ่งครั้งในการสร้างอินสแตนซ์คลาส ด้วยตะขอดูเหมือนว่า useState จะถูกเรียกทุกครั้งที่เรียกใช้ฟังก์ชันและทุกครั้งที่ควรเริ่มต้นสถานะ แต่มี "เวทมนตร์" ที่ไม่สามารถอธิบายได้เกิดขึ้นที่นั่น
vitalyster

บางทีโพสต์นี้อาจทำให้เกิดความกระจ่างได้stackoverflow.com/questions/54673188/…
Shubham Khatri

หากคุณต้องการรวมอุปกรณ์ประกอบฉากเข้าด้วยกันคุณจะติดอยู่ในลูปที่ไม่มีที่สิ้นสุดเมื่อใช้ create-react-app ซึ่งต้องการให้สถานะอยู่ในอาร์เรย์ที่ต้องพึ่งพา
user210757

2
สิ่งนี้จบลงด้วยการตั้งค่าสถานะเริ่มต้นสองครั้งซึ่งค่อนข้างน่ารำคาญ ฉันสงสัยว่าคุณสามารถตั้งค่าสถานะเริ่มต้นเป็นโมฆะแล้วใช้React.useEffectเพื่อตั้งค่าสถานะเริ่มต้นในแต่ละครั้งได้หรือไม่
CMCDragonkai

2
สิ่งนี้จะไม่ได้ผลหากรัฐควบคุมการแสดงผลด้วย ฉันมีส่วนประกอบการทำงานที่แสดงผลตามอุปกรณ์ประกอบฉากและการแสดงผลตามสถานะ หากสถานะบอกให้คอมโพเนนต์แสดงผลเนื่องจากมีการเปลี่ยนแปลง useEffect จะทำงานและตั้งค่าสถานะกลับเป็นค่าเริ่มต้น นี่เป็นการออกแบบที่แย่มากในส่วนของพวกเขา
Greg Veres

1

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

เช่นกรณีของคุณสิ่งนี้จะทำงานของคุณ

 React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

ฟังก์ชันที่ส่งผ่านไปยัง useEffect จะทำงานหลังจากการแสดงผลถูกส่งไปที่หน้าจอ

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

React.useEffect(FunctionYouWantToRunAfterEveryRender)

หากคุณส่งอาร์กิวเมนต์เดียวเพื่อ useEffect มันจะเรียกใช้เมธอดนี้ทุกครั้งหลังการเรนเดอร์คุณสามารถตัดสินใจได้ว่าจะเริ่มการทำงานนี้เมื่อใดFunctionYouWantToRunAfterEveryRenderโดยส่งอาร์กิวเมนต์ที่สองไปที่ useEffect

React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])

อย่างที่คุณสังเกตว่าฉันกำลังส่ง [props.user] ตอนนี้useEffectจะเริ่มการFunctionYouWantToRunAfterEveryRenderทำงานของฟังก์ชันนี้เมื่อprops.userมีการเปลี่ยนแปลงเท่านั้น

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


0

พารามิเตอร์ที่ส่งไปReact.useState()เป็นเพียงค่าเริ่มต้นสำหรับสถานะนั้น การตอบสนองจะไม่รับรู้ว่าเมื่อเปลี่ยนสถานะเพียงแค่ตั้งค่าเริ่มต้นเท่านั้น คุณจะต้องตั้งค่าสถานะเริ่มต้นในตอนแรกจากนั้นจึงเรียกแบบมีเงื่อนไขsetUser(newValue)ซึ่งจะรับรู้ว่าเป็นสถานะใหม่และแสดงองค์ประกอบอีกครั้ง

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


-2

ตามเอกสาร ReactJS เกี่ยวกับ Hooks :

แต่จะเกิดอะไรขึ้นถ้าเพื่อน prop เปลี่ยนไปในขณะที่ส่วนประกอบอยู่บนหน้าจอ? ส่วนประกอบของเราจะแสดงสถานะออนไลน์ของเพื่อนคนอื่นต่อไป นี่คือบั๊ก นอกจากนี้เรายังอาจทำให้หน่วยความจำรั่วหรือขัดข้องเมื่อยกเลิกการต่อเชื่อมเนื่องจากการโทรยกเลิกการสมัครจะใช้รหัสเพื่อนที่ไม่ถูกต้อง

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

PS: ฉันมีรหัสไม่เพียงพอที่จะตัดสิน แต่คุณไม่สามารถ setUser () ในฟังก์ชัน Avatar (อุปกรณ์ประกอบฉาก) ของคุณได้หรือไม่?


-12

ในโลกแห่งปฏิกิริยาคุณควรอัปเดตสถานะของคุณในฟังก์ชัน componentWillRecieveProps (nextProps) ในกรณีเช่นนี้


4
ซึ่งไม่เป็นความจริงอีกต่อไปสำหรับ react รุ่นล่าสุด
Shubham Khatri
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.