添加联系人触发Maximum call stack size exceeded错误求助
问题:添加联系人时触发Maximum call stack size exceeded错误
原本应用运行正常,添加删除联系人功能后,点击添加新联系人时出现栈溢出错误。以下是相关代码:
App.js
import { useEffect, useState } from 'react'; import { AddContact } from './AddContact'; import { ContactList } from './ContactList'; import { Header } from './Header'; import { uuid } from 'uuidv4'; function App() { const objKey ='contacts' const [contacts,setContacts]=useState([]); const detailsToParent = (contact) => { const newContact = { id: uuid(), ...contact }; const updatedContacts = [...contacts, newContact]; setContacts(updatedContacts); // Update the state first localStorage.setItem(objKey, JSON.stringify(updatedContacts)); }; useEffect(() => { const localArray = JSON.parse(localStorage.getItem(objKey)); if (localArray) setContacts(localArray); }, []); const deleteContactHandler = (id) => { const remainingContacts = contacts.filter((contact) => contact.id !== id); setContacts(remainingContacts); }; return ( <div> <Header/> <AddContact detailsToParent={detailsToParent}/> <ContactList contacts={contacts} getContactId={deleteContactHandler} /> </div>) } export default App;
ContactList.js
import { Delete } from '@mui/icons-material'; import { Avatar } from '@mui/material'; import React from 'react'; export const ContactList = (props) => { const list = props.contacts.map((contact) => { return ( <div className='d-flex shadow m-2 rounded p-4 bg-light justify-content-between align-items-end' > <div className='d-flex'> <Avatar className='me-4' style={{ color: 'blue' }} /> <div> <div> <b>{contact.name}</b> </div> <div>{contact.email}</div> </div> </div> <Delete onClick={() => props.getContactId(contact.id) } key={contact.id} style={{ color: 'red' }} /> </div> ); }); return ( <div> <h5 className='ms-4 mt-4'>Contacts</h5> {list} </div> ); };
AddContact.js
import React from 'react' export const AddContact = (props) => { const details={ }; function add(e){ e.preventDefault(); var name = document.getElementById('name').value; var email = document.getElementById('email').value; details.name=name details.email=email document.getElementById('name').value=document.getElementById('name').defaultValue document.getElementById('email').value=document.getElementById('email').defaultValue if (details.name==='' || details.email===''){ alert('all the fields are mandatory!'); return } props.detailsToParent(details); } return ( <> <div className='ps-3'> <div className='mt-2 fs-2 fw-bold'> Add Contact </div> <form onSubmit={(e) => add(e)}> <div> <label for='name' className='m-1 fw-bold'>Name </label><br/> <input type='text' placeholder='name' name='name' id='name' className='m-1 h-2 b-0 form-control'/> </div> <div> <label for='email' className='m-1 fw-bold'>Email</label> <br/> <input type='email' placeholder='example@gmail.com' name='email' className='m-1 b-0 form-control' id='email'/> </div> <input type='submit' value='add' className='btn btn-primary p-2 mt-2 px-5'/> </form> </div> </> ) }
问题根源及修复方案
1. 列表元素缺失正确key
ContactList中map返回的外层div未设置唯一key,React无法正确追踪列表元素,导致渲染循环引发栈溢出。将key移至外层div:
// ContactList.js修改后 <div key={contact.id} className='d-flex shadow m-2 rounded p-4 bg-light justify-content-between align-items-end' > // ...其余代码 </div>
2. 状态更新的闭包问题
deleteContactHandler直接使用当前contacts状态,可能获取到旧值引发异常。改用函数式更新获取最新状态:
// App.js修改后 const deleteContactHandler = (id) => { setContacts(prevContacts => prevContacts.filter((contact) => contact.id !== id)); };
3. localStorage保存时机错误
setContacts是异步操作,直接同步保存可能存入旧状态。改用useEffect监听contacts变化自动保存:
// App.js添加以下代码 useEffect(() => { localStorage.setItem(objKey, JSON.stringify(contacts)); }, [contacts]); // 同时修改detailsToParent,移除内部的localStorage操作 const detailsToParent = (contact) => { const newContact = { id: uuid(), ...contact }; setContacts(prevContacts => [...prevContacts, newContact]); };
4. 共享对象引用导致的状态异常
AddContact中details是组件内共享变量,每次添加复用同一引用,可能引发状态更新异常。在add函数内创建新对象:
// AddContact.js修改后 function add(e){ e.preventDefault(); const name = document.getElementById('name').value; const email = document.getElementById('email').value; // 每次创建新对象 const details = { name, email }; document.getElementById('name').value = ''; document.getElementById('email').value = ''; if (details.name === '' || details.email === ''){ alert('所有字段均为必填项!'); return; } props.detailsToParent(details); }
另外,修正AddContact中label的for属性为React规范的htmlFor。
内容的提问来源于stack exchange,提问作者DHANUKONDA SAI ROHITH
相关产品推荐
相关产品推荐

