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

如何更新React状态以在嵌套数组中添加元素:为指定索引的人员新增手机号

How to Add a New Phone Number to a Specific Person in React State

Got it, let's break down how to handle this properly while respecting React's immutable state rules—this is key to making sure your UI updates correctly.

The Core Idea: Avoid Direct Mutation

React relies on immutable state updates to detect changes and re-render components. That means you can't just push a new phone number directly into the existing phoneNumbers array; you need to create copies of the arrays/objects you're modifying.

Step-by-Step Solution

Here's a dedicated function to add a phone number to the person at index i:

const addPhoneNumberToPerson = (i) => {
  // Use functional update to get the latest state safely
  setPersons(prevPersons => {
    // 1. Make a copy of the entire persons array
    const updatedPersons = [...prevPersons];
    // 2. Make a copy of the target person's object (so we don't mutate the original)
    const updatedPerson = { ...updatedPersons[i] };
    // 3. Copy the phoneNumbers array and add a new empty string to it
    updatedPerson.phoneNumbers = [...updatedPerson.phoneNumbers, ""];
    // 4. Replace the old person in the array with our updated one
    updatedPersons[i] = updatedPerson;
    // 5. Return the new array to update the state
    return updatedPersons;
  });
};

Why This Works:

  • We use setPersons(prevPersons => ...) instead of referencing the persons state directly. This ensures we're always working with the latest version of the state, which prevents bugs from stale closures (super important if multiple state updates happen quickly).
  • We create copies at every nested level: the main persons array, the individual person object, and the phoneNumbers array. This keeps the original state untouched, letting React detect the change and re-render the component.

Full Working Example

To see this in context, here's a complete component that includes adding new people, updating their details, and adding phone numbers:

import { useState } from 'react';

function PersonManager() {
  const [persons, setPersons] = useState([
    { name: "", age: "", phoneNumbers: [''] },
  ]);

  const addPersonFields = () => {
    const newPerson = { name: "", age: "", phoneNumbers: [""], };
    setPersons(prev => [...prev, newPerson]);
  };

  const addPhoneNumberToPerson = (i) => {
    setPersons(prevPersons => {
      const updatedPersons = [...prevPersons];
      const updatedPerson = { ...updatedPersons[i] };
      updatedPerson.phoneNumbers = [...updatedPerson.phoneNumbers, ""];
      updatedPersons[i] = updatedPerson;
      return updatedPersons;
    });
  };

  // Bonus: Handle input updates for name, age, and phone numbers
  const updateField = (personIndex, field, value) => {
    setPersons(prev => {
      const updated = [...prev];
      updated[personIndex] = { ...updated[personIndex], [field]: value };
      return updated;
    });
  };

  const updatePhoneNumber = (personIndex, phoneIndex, value) => {
    setPersons(prev => {
      const updated = [...prev];
      updated[personIndex] = { ...updated[personIndex] };
      updated[personIndex].phoneNumbers = [...updated[personIndex].phoneNumbers];
      updated[personIndex].phoneNumbers[phoneIndex] = value;
      return updated;
    });
  };

  return (
    <div style={{ padding: '20px' }}>
      {persons.map((person, i) => (
        <div key={i} style={{ marginBottom: '15px', padding: '10px', border: '1px solid #eee' }}>
          <div>
            <input
              placeholder="Name"
              value={person.name}
              onChange={(e) => updateField(i, 'name', e.target.value)}
              style={{ marginRight: '10px' }}
            />
            <input
              placeholder="Age"
              value={person.age}
              onChange={(e) => updateField(i, 'age', e.target.value)}
            />
          </div>
          <div style={{ marginTop: '10px' }}>
            {person.phoneNumbers.map((phone, j) => (
              <input
                key={j}
                placeholder="Phone Number"
                value={phone}
                onChange={(e) => updatePhoneNumber(i, j, e.target.value)}
                style={{ marginRight: '10px', marginBottom: '5px' }}
              />
            ))}
            <button onClick={() => addPhoneNumberToPerson(i)}>
              + Add Phone
            </button>
          </div>
        </div>
      ))}
      <button onClick={addPersonFields}>+ Add New Person</button>
    </div>
  );
}

export default PersonManager;

内容的提问来源于stack exchange,提问作者Bhukailas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:59:08