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