Dalam komponen pelajar (kanak-kanak)
useEffect
挂钩将通过 handleStudentsChange
(fungsi yang disediakan oleh komponen induk) mengemas kini tatasusunan induk. Dalam komponen pelajar (ibu bapa)
handleStudentsChange
函数使用 useCallback
definisi cangkuk. Namun, ia nampaknya tidak berkesan. Soalan/Soalan
handleStudentsChange
akan berjalan selama-lamanyaLihat kod di sini: Saya adalah pautan CodeSandBox
Pelajar.tsx(Anak)
import React, { useState, useEffect, useRef } from "react"; import TextField from "@mui/material/TextField"; interface student { firstName: string; lastName: string; grade: number; } interface studentProps { id: number; firstName: string; lastName: string; grade: number; handleStudentsChange: (index: number, student: student) => void; } function Student(props: studentProps) { const [firstName, setFirstName] = useState(props.firstName); const [lastName, setLastName] = useState(props.lastName); const [grade, setGrade] = useState(props.grade); useEffect(() => { handleStudentsChange(id, { firstName: firstName, lastName: lastName, grade: grade }); }, [firstName, lastName, grade, props]); return ( <> <TextField label="firstName" onChange={(event) => setFirstName(event.target.value)} value={firstName} /> <TextField label="lastName" onChange={(event) => setLastName(event.target.value)} value={lastName} /> <TextField label="grade" onChange={(event) => setGrade(+event.target.value)} value={grade} /> </> );
Pelajar.tsx(ibu bapa)
import React, { useState, useCallback } from "react"; import Student from "./Student"; interface student { firstName: string; lastName: string; grade: number; } export default function Students() { const [students, setStudents] = useState<student[]>([ { firstName: "Justin", lastName: "Bieber", grade: 100 }, { firstName: "Robert", lastName: "Oppenhiemer", grade: 100 } ]); const handleStudentsChange = useCallback( (index: number, updatedStudent: student) => { // console.log(index) //I only want this to rerender when the value change however it turn into an infinity loop setStudents((prevStudents) => { const updatedStudents = [...prevStudents]; updatedStudents[index] = updatedStudent; return updatedStudents; }); }, [] ); return ( <> {students.map((student, index) => { return ( <Student key={index} id={index} firstName={student.firstName} lastName={student.lastName} grade={student.grade} handleStudentsChange={(index: number, newStudent: student) => handleStudentsChange(index, newStudent) } /> ); })} </> ); }
Seperti yang ditunjukkan dalam kod di atas, saya cuba menggunakan React.memo
pada komponen pelajar (kanak-kanak) dan useCallback
pada React.memo
,并在 handleStudentsChange
上使用 useCallback
dengan harapan dapat menghalang gelung tak terhingga. Walau bagaimanapun, gelung tak terhingga berterusan.
Soalan
handleStudentsChange
不仅在发生更改时无限运行一次-它从第一次渲染开始就无限运行。这是因为Student
组件具有调用handleStudentsChange
的useEffect
,它更新了Students
组件中的状态,导致Student
组件重新渲染,然后再次调用useEffect
, gelung tak terhingga.Penyelesaian
Anda perlu memanggil negeri dalam
handleStudentsChange
,而不是在每次渲染后都调用。我在下面的示例中包含了一个示例,它在从输入触发blur
事件后更新了Students
hanya selepas mengemas kini input. Untuk pendekatan yang lebih bijak (dan lebih kompleks), anda boleh membandingkan prop dan keadaan untuk memutuskan sama ada kemas kini diperlukan, tetapi saya akan membenarkan anda memikirkannya sendiri.