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

}
Orionss
  • 725
  • 2
  • 10
  • 26
joy08
  • 9,004
  • 8
  • 38
  • 73
  • I think this thread will help you : https://stackoverflow.com/questions/29537299/react-how-do-i-update-state-item1-on-setstate-with-jsfiddle In any case, you're forced to setState the entire array just to modify a single case of your array. – Orionss May 15 '19 at 10:34

1 Answers1

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,
       }));
}
xadm
  • 8,219
  • 3
  • 14
  • 25
Orionss
  • 725
  • 2
  • 10
  • 26
  • 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 ? – Orionss May 15 '19 at 10:57
  • 2
    `users.push( newEmptyObject )` before `setState()` – xadm May 15 '19 at 11:03
  • Why would you do this ? – Orionss May 15 '19 at 11:05
  • @Orionss, Is there a way where I can combine both of these and do both the actions in a single setState? – joy08 May 15 '19 at 11:06
  • 1
    @velsonjr Yes, by pushing into the array before the setState – Orionss May 15 '19 at 11:07
  • @xadm Could you please edit the snippet? It will be helpful – joy08 May 15 '19 at 11:07
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/193390/discussion-between-orionss-and-velsonjr). – Orionss May 15 '19 at 11:13
  • updated, of course you could use sth like ` `this.setState({ users: [...users, {firstname:'',lastname:'',phone:''updateButtonFlag:false} ] });` - a bit safer (new array) – xadm May 15 '19 at 11:19