Reputation: 525
I have a state in Parent Component that has an Array of patients. My Child Component 4
is a Countdown component
(// countdown component renders individually countdown for each patient in the array) and when the countdown gets to <=0, I would like to reset the patient’s locationInfo & status
value to be empty string in the patient array. In my parent component, I have resetPatient
function that maps over the patient array
and should set the values(locationInfo & status)
of the patient that has <=0 counter to empty strings. The resetPatient function is passed as props down to my Countdown component(4). In Countdown component I call the this.props.resetPatient
function when the counter gets to <=0. However, this is not working for me. The state on Parent Component doesn’t change.
Parent Component
- Child Component 1
- Child Component 2
- Child Component 3
- Child Component 4
Parent component
export default class ObservationWorkflow extends React.Component {
constructor(props) {
super(props);
this.state = {
patients = [
{ room: "1", name: 'John', locationInfo: 'TV', status: 'Awake'},
{ room: "2", name: 'Shawn, locationInfo: 'Toilet', status: 'Awake'},
{ room: "3", name: 'Gereth, locationInfo: 'Garden', status: 'Awake'}
]
}
this.resetPatient = this.resetPatient.bind(this);
}
resetPatient = (patient, index) => {
this.setState(prevState => ({
patients: prevState.patients.map((patient, i) => {
if (i === index) {
return {
...patient,
locationInfo: '',
status: ''
};
}
return patient;
}),
}));
}
render() {
return (
<Child component(1)={this.resetPatient} // then child component 2 passes it down as props to 3 then 4.
)
}
}
Countdown component(4)// countdown component renders individually countdown for each patient in the array.
export default class ObservationCountDown extends React.Component {
constructor(props) {
super(props);
this.state = {
obsTimeleft: undefined
};
this.countDown = this.countDown.bind(this);
this.startCountdown = this.startCountdown.bind(this);
this.countDownInterval = null;
}
countDown() {
const { obsTakenTime, patient, index } = this.props;
const nextDueTimeForObs = moment(obsTakenTime).add(10, 'minutes');
const nextObservationTime = nextDueTimeForObs.subtract(moment.now()).format('mm');
if (obsTakenTime) {
this.setState({ obsTimeleft: nextObservationTime + ' mins' });
}
if (Number(nextObservationTime) <= 1) {
this.props.disablePatientUpdate();
}
if (Number(nextObservationTime) <= 0) {
this.setState({ obsTimeleft: 'Overdue' });
this.props.enablePatientUpdate();
clearInterval(this.countDownInterval);
() => this.props.resetPatient(patient, index); // here i call the function as call back
}
}
How to set the state of parent component from a child component in react.
Upvotes: 0
Views: 135
Reputation: 9907
It looks like you're not calling resetPatient
, and that index
isn't defined in that scope in any case.
I would add an id
to your patient object and use this to identify which one needs to be reset:
patients = [
{ id:1, room: "1", name: 'John', locationInfo: 'TV', status: 'Awake'},
{ id:2, room: "2", name: 'Shawn, locationInfo: 'Toilet', status: 'Awake'},
{ id:3, room: ... }]
and your resetPatient
would become:
resetPatient = (patient) => {
this.setState(prevState => ({
patients: prevState.patients.map(p => {
if (patient.id === p.id) {
return {
...p,
locationInfo: '',
status: ''
};
}
return p;
}),
}));
}
Then you can just call:
this.props.resetPatient(patient)
Upvotes: 1
Reputation: 169
First, you do not need anymore this.resetPatient = this.resetPatient.bind(this);
when you are already using arrow function at resetPatient = (patient, index) => {...}
Second, pass your callback like this :
<Child resetPatient= { this.resetPatient } />
and then access it in child as props :
this.props.resetPatient(..., ...)
Hope it helps
Upvotes: 1
Reputation: 409
try calling the function like this
this.props.resetPatient(patient, index);
by doing () => this.props.resetPatient(patient, index);
you are just declaring another function which you have to call again,
you can change it to
(() => this.props.resetPatient(patient, index))();
But that seems rather unnecessary.
Upvotes: 0