'setState data updating one iteration late in parent - ReactJS
The setState data in child is updating one iteration late in parent. My goal is that any time a value changes in child component I get the new updated field plus all the old ones in parent. The log line in parent shows the state data, all fields, but 1 iteration late. That is if I write "A" in Milestone Name console prints empty now if update it to "B" is shows "A" in console that is previous iteration
ConfigureCalenderForm.js (Parent Component)
import React, { useState } from 'react';
import MilestoneDetails from './MilestoneDetails';
import './ConfigureCalenderForm.css';
const ConfigureCalenderForm = () => {
const milestoneDetailsChangeHandler = (milestoneDetails) => {
console.log(milestoneDetails);
};
return (
<div className='configure-calender__container'>
<form>
<MilestoneDetails
onMilestoneDetailsUpdate={milestoneDetailsChangeHandler}
/>
<div className='row configure-calender__actions'>
<Button
className='primary-blue small'
icon={{
color: '#fff',
icon: 'checkMark',
size: 'medium',
isRequired: {},
}}
label='Save Milestone'
/>
</div>
</form>
</div>
);
};
export default ConfigureCalenderForm;
MilestoneDetails.js (Child Component)
import React, { useState } from 'react';
import './MilestoneDetails.css';
const MilestoneDetails = (props) => {
const [enteredName, setEnteredName] = useState('');
const [enteredDate, setEnteredDate] = useState('');
const [enteredDescription, setEnteredDescription] = useState('');
const nameChangedHandler = (event) => {
setEnteredName(event.target.value);
const milestoneDetails = {
enteredName: enteredName,
enteredDate: new Date(enteredDate),
enteredDescription: enteredDescription,
};
props.onMilestoneDetailsUpdate(milestoneDetails);
};
const dateChangedHandler = (event) => {
setEnteredDate(event.target.value);
const milestoneDetails = {
enteredName: enteredName,
enteredDate: new Date(enteredDate),
enteredDescription: enteredDescription,
};
props.onMilestoneDetailsUpdate(milestoneDetails);
};
const descriptionChangedHandler = (event) => {
setEnteredDescription(event.target.value);
const milestoneDetails = {
enteredName: enteredName,
enteredDate: new Date(enteredDate),
enteredDescription: enteredDescription,
};
props.onMilestoneDetailsUpdate(milestoneDetails);
};
return (
<div className='milestone__controls'>
<div className='milestone__row'>
<div className='milestone__control'>
<label>Milestone Name</label>
<input
type='text'
placeholder='Please Enter'
value={enteredName}
onChange={nameChangedHandler}
/>
</div>
<div className='milestone__control'>
<label>Milestone Date</label>
<input
type='date'
placeholder='Please Select'
value={enteredDate}
onChange={dateChangedHandler}
/>
</div>
</div>
<div className='milestone__row'>
<div className='milestone__controlTextArea'>
<label>Milestone Description</label>
<textarea
className='milestone__TextArea'
placeholder='Please Enter'
maxLength={'50'}
value={enteredDescription}
onChange={descriptionChangedHandler}
/>
</div>
</div>
</div>
);
};
export default MilestoneDetails;
Solution 1:[1]
yes that is how the state works . you call setState then react would schedule an update to compute what it needs in the next render, so through out the execution of the function - dateChangeHandler for example - you still see the old state, and to send the new state to the parent send the event.target.value instead of enterdDate.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mahmed nabil |
