Rayden Storm نشر 26 فبراير 2021 أرسل تقرير نشر 26 فبراير 2021 اذا كان ال state بسيط فيمكنني تغييره عن طريق setForm((prevForm) => ({ ...prevForm, [name]: value })); ماذا ان كان ال state معقد بهذا الشكل function App() { const [form, setForm] = useState({ info: { firstname: '', lastname: '', email: '', password: '', confirmPassword: '' }, address: { country: '', city: '', line1: '', line2: '' }, }); const handleChange = (e) => { const { name, value } = e.target; setForm((prevForm) => ({ ...prevForm, [name]: value })); }; console.log(form); return ( <div> <h2>signup</h2> <input type="text" placeholder="firstname" name="firstname" value={form.info.firstname} onChange={handleChange} /> <input type="text" placeholder="lastname" name="lastname" value={form.info.lastname} onChange={handleChange} /> <input type="email" placeholder="email" name="email" value={form.info.email} onChange={handleChange} /> <input type="password" placeholder="password" name="password" value={form.info.password} onChange={handleChange} /> <input type="password" placeholder="confirmPassword" name="confirmPassword" value={form.info.confirmPassword} onChange={ handleChange} /> <input type="text" placeholder="country" name="country" value={form.address.country} onChange={ handleChange} /> <input type="text" placeholder="city" name="city" value={form.address.city} onChange={ handleChange} /> <input type="text" placeholder="line1" name="line1" value={form.address.line1} onChange={ handleChange} /> <input type="text" placeholder="line2" name="line2" value={form.address.line2} onChange={ handleChange} /> </div> ); } export default App; اقتباس
0 Salah Eddin Beriani2 نشر 26 فبراير 2021 أرسل تقرير نشر 26 فبراير 2021 في حالتك انت تحتاج الى متغير اخر ليساعدك في تحديد اسم الطبقة التي تريد تغييرها ويمكنك ان تعطيها الى handleChange بهذا الشكل onChange={(e) => handleChange(e, 'اسم الطبقة')} ثم يمكنك الاعتماد على ذلك لتغيير ال state بهذا الشكل const handleChange = (e, objKey) => { const { name, value } = e.target; setForm((prevForm) => ({ ...prevForm, [objKey]: { ...prevForm[objKey], [name]: value } })); }; function App() { const [form, setForm] = useState({ info: { firstname: '', lastname: '', email: '', password: '', confirmPassword: '' }, address: { country: '', city: '', line1: '', line2: '' }, }); const handleChange = (e, objKey) => { const { name, value } = e.target; setForm((prevForm) => ({ ...prevForm, [objKey]: { ...prevForm[objKey], [name]: value } })); }; console.log(form); return ( <div> <h2>signup</h2> <input type="text" placeholder="firstname" name="firstname" value={form.info.firstname} onChange={(e) => handleChange(e, 'info')} /> <input type="text" placeholder="lastname" name="lastname" value={form.info.lastname} onChange={(e) => handleChange(e, 'info')} /> <input type="email" placeholder="email" name="email" value={form.info.email} onChange={(e) => handleChange(e, 'info')} /> <input type="password" placeholder="password" name="password" value={form.info.password} onChange={(e) => handleChange(e, 'info')} /> <input type="password" placeholder="confirmPassword" name="confirmPassword" value={form.info.confirmPassword} onChange={(e) => handleChange(e, 'info')} /> <input type="text" placeholder="country" name="country" value={form.address.country} onChange={(e) => handleChange(e, 'address')} /> <input type="text" placeholder="city" name="city" value={form.address.city} onChange={(e) => handleChange(e, 'address')} /> <input type="text" placeholder="line1" name="line1" value={form.address.line1} onChange={(e) => handleChange(e, 'address')} /> <input type="text" placeholder="line2" name="line2" value={form.address.line2} onChange={(e) => handleChange(e, 'address')} /> </div> ); } export default App; 1 اقتباس
0 أحمد حبنكة نشر 26 فبراير 2021 أرسل تقرير نشر 26 فبراير 2021 في حالتك يجب نسخ state object قبل التعديل هكذا: const handleChange = (e) => { const { name, value } = e.target; setForm((prevForm) => { const newForm = {...prevForm}; newForm.info[name] = value; return newForm; }); }; الكود السابق سيعمل لكن المشكلة الوحيدة أننا نقوم بعمل shallow copy وليس deep copy، مشكلة الـshallow copy أنها لا تضمن immutability ﻷننا في الحالة السابقة نعدل على info بشكل مباشر وهذا سيعدل على state بشكل مباشر وهذا خاطئ وإن عمل الكود، في حالة أردنا deep copy أنا أفضل حينها استخدام مكتبة immer من هذا الرابط ، في حالتك باستعمال immer: const handleChange = (e) => { const { name, value } = e.target; setForm((prevForm) => { return produce(prevForm,(draftForm) => { draftForm.info[name] = value; }); }); }; لاحظ أن الكود السابق أسهل بكثير فيم لو قمنا بعمل deep copy بأيدينا حيث تضمن لك مكتبة immer أن تكون state لديك immutable بشكل كامل ومع ذلك تكتب كود مشابه للـmutable. إذا كان state object أعقد بكثير من حالتك هنا أفضل استعمال مكتبة redux وredux-toolkit أو أي بديل تحت مسمى state management library (مثل Mobx مثلاً) حيث تسمح لك تلك المكتبات بتقسيم state الكبيرة إلى أجزاء صغيرة يعالج كل جزء فيها معالجة مستقلة عن بقية الأجزاء مما يجعل إدارة الـstate object الكبير أسهل ناهيك عن توفير ميزات أخرى مثل تنظيم هيكلية التطبيق بنظام موحد جميل وأشياء أخرى كثيرة. 1 اقتباس
السؤال
Rayden Storm
اذا كان ال state بسيط فيمكنني تغييره عن طريق
setForm((prevForm) => ({ ...prevForm, [name]: value }));
ماذا ان كان ال state معقد بهذا الشكل
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.