首页 > 解决方案 > 在 React setState 中更新嵌套数组元素

问题描述

我正在维护一个存储在状态对象中的对象数组。基本上,每当我单击“添加”按钮时,我都会将每个对象推送到该数组中。这会将这个对象存储在数组中。

我正在维护一个标志 updateButtonFlag 以显示该特定帐户的更新按钮。

我想更新刚刚提交的帐户的这个标志(即在 onAddAccount() 函数中)。

添加后,将显示带有输入字段的新卡片,以便输入下一个用户详细信息

帮助将不胜感激


//Have included only onAddAccount function ,where the logic needs to go.
//There is a fetch call as well, which basically displays accounts info if there are any accounts w.r.t to that user

import * as React from 'react';

interface IState{
    users : Account[];
    user: Account
}
interface Account{
  name: string;
  email: string;
  phone: string;
  updateButtonFlag: boolean 
}

export default class App extends React.Component<{},IState> {

    constructor(props:any){
       super(props);
       this.state= { 
                         users: [],
                         user: null
                   }
    }

    async componentDidMount(){

      let useraccounts =  await this.fetchAccounts(); // call that returns  accounts, if present
      let id:any, account: IAccount ;      
      if(useraccounts.length === 0) // if no account, display an empty card
      {
         this.setState({ accounts: [...this.state.accounts, {firstname:'',lastname:'',phone:'',updateButtonFlag: false}]},()=>{});
      }

      if(useraccounts.length > 0) // if there are accounts existing, display themand add update button to them
      { 
        let accountArray = [];

        for(let i=0;i<useraccounts.length;i++)
        {
             account = {
                       firstsname: useraccounts[i].firstsname,
                       lastname: useraccounts[i].lastname,
                       phone: useraccounts[i].phone,
                       updateButtonFlag: true
                     }
            accountArray.push(account);
          }
           this.setState(({accounts}) => ({accounts: [...accounts, ...accountArray]}),()=>{});
       }    
      }

    onAddAccount = (index:number) => { // this adds one more card with input fields after submission of current user info

      let { users } =  this.state;
      let account : IAccount = {firstname: users[index].firstname, lastname: users[index].lastname , phone: users[index].phone, updateButtonFlag:false}  // maintaining a updateflag to show update button for the corresponding account
      this.submit(account);  // submit call  to submit the account details
      //here i need to update the flag of currently submitted account to true, so that update button gets shown , how to do it?

      this.setState((prevState) => ({
             users: [ ...prevState.users, {firstname:'',lastname:'',phone:''updateButtonFlag:false} ],
       }));
      } // in this line,next card gets added here

    }
  renderAccounts = (users: Account[]) => {
    return accounts.map((value, index) => {
      return (
        <div key={index}>
          <div>
            <form>
              <label>First Name:</label>
              <input
                type="text"
                name="firstname"
                value={value.firstname}
                onChange={e => this.handleChange(e, index)}
                required
              />
              <label>Last Name:</label>
              <input
                type="text"
                name="lastname"
                value={value.lastname}
                onChange={e => this.handleChange(e, index)}
              />
              <label>Age:</label>
              <input
                type="text"
                name="age"
                value={value.age}
                onChange={e => this.handleChange(e, index)}
                required
              />
              <div>
                  <button onClick={() => this.onAddAccount(index)}>
                    Save & Add Another Account
                  </button>
                  {users[index].updatedButtonFlag?<button onClick={() => this.onUpdateAccount(index)}>
                     Update Account
                  </button> :null}
                  <button onClick={() => this.onRemoveAccount(index)}>
                    Remove Account
                  </button>
                )}
              </div>
            </form>
          </div>
        </div>
      );
    });
  };

  render() {
    return <div>{this.renderAccounts(accounts)}</div>;
  }
}

}

标签: reactjstypescriptsetstate

解决方案


按照我在这个线程上看到的,您不能使用 setState 来更新嵌套对象。因此,在您的情况下,您必须更新整个数组。

onAddAccount = (index:number) => {
      let { users } =  this.state;
      let account : IAccount = {firstname: users[index].firstname, lastname: users[index].lastname , phone: users[index].phone, updateButtonFlag:false}
      this.submit(account);
      users[index].updateButtonFlag = true;
      users.push({firstname:'',lastname:'',phone:'',updateButtonFlag:false}); // Add an empty account
      this.setState({
             users: users,
       }));
}

推荐阅读