0

I am maintaining an array of objects which is stored in a state object. Basically I am pushing each object to this array whenever I click on Add button .This stores this object in array.

I am maintaining a flag updateButtonFlag to show the update button for that particular account.

I want to update this flag of an account that just got submitted(that is in onAddAccount() function).

After addition , a new card gets displayed with input fields, so that next user details can be entered

Help would be appreciated


//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>;
  }
}

}
1
  • I think this thread will help you : stackoverflow.com/questions/29537299/… In any case, you're forced to setState the entire array just to modify a single case of your array. Commented May 15, 2019 at 10:34

1 Answer 1

1

Following what I saw on this thread, you cannot use setState to update nested objects. So, in your case, you'll have to update the entire array.

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,
       }));
}
Sign up to request clarification or add additional context in comments.

8 Comments

Each time you'll want to update a user, you'll have to extract the array, modify the user you want and setState the entire array. Did it help ?
users.push( newEmptyObject ) before setState()
Why would you do this ?
@Orionss, Is there a way where I can combine both of these and do both the actions in a single setState?
@velsonjr Yes, by pushing into the array before the setState
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.