You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加联系人触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:38:12