Как установить состояние родительского компонента из дочернего компонента в React?

У меня есть состояние в родительском компоненте, в котором есть массив пациентов. My Child Component 4 - это Countdown component (// компонент обратного отсчета визуализирует индивидуальный обратный отсчет для каждого пациента в массиве), и когда обратный отсчет дойдет до ‹= 0, я хотел бы сбросить значение locationInfo & status пациента, чтобы оно было пустой строкой в ​​массиве пациентов. В моем родительском компоненте у меня есть функция resetPatient, которая отображает patient array и должна устанавливать значения(locationInfo & status) пациента, у которого счетчик ‹= 0, на пустые строки. Функция resetPatient передается как подпорка моему компоненту обратного отсчета (4). В компоненте обратного отсчета я вызываю функцию this.props.resetPatient, когда счетчик достигает ‹= 0. Однако у меня это не работает. Состояние родительского компонента не меняется.

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

Как установить состояние родительского компонента из дочернего компонента в react.


person Jereme    schedule 23.09.2019    source источник
comment
Возможный дубликат stackoverflow.com/ questions / 29100774 /   -  person barteezy    schedule 23.09.2019
comment
в вашем компоненте (4), откуда берется индекс? вы, например, не передаете это своему Родителю.   -  person Will Jenkins    schedule 23.09.2019


Ответы (3)


Похоже, вы не вызываете resetPatient, и этот index в любом случае не определен в этой области.

Я бы добавил id к вашему объекту пациента и использовал его, чтобы определить, какой из них нужно сбросить:

 patients = [
       { id:1, room: "1", name: 'John', locationInfo: 'TV', status: 'Awake'},
       { id:2, room: "2", name: 'Shawn, locationInfo: 'Toilet', status: 'Awake'},
       { id:3, room: ... }]

и ваш resetPatient станет:

 resetPatient = (patient) => {

    this.setState(prevState => ({

        patients: prevState.patients.map(p => {
            if (patient.id === p.id) {
                return {
                    ...p,
                    locationInfo: '', 
                    status: ''
                };
            }
            return p;
        }),
    }));
}

Тогда вы можете просто позвонить:

   this.props.resetPatient(patient)
person Will Jenkins    schedule 23.09.2019

Во-первых, вам больше не нужно this.resetPatient = this.resetPatient.bind(this);, если вы уже используете стрелочную функцию в resetPatient = (patient, index) => {...}

Во-вторых, передайте обратный вызов следующим образом:

<Child resetPatient= { this.resetPatient } />

а затем получить доступ к нему в дочернем элементе как реквизит:

 this.props.resetPatient(..., ...)

Надеюсь, это поможет

person N. Henoc HOUNSA    schedule 23.09.2019

попробуйте вызвать такую ​​функцию

this.props.resetPatient(patient, index);

делая () => this.props.resetPatient(patient, index);, вы просто объявляете другую функцию, которую вам нужно вызвать снова, вы можете изменить ее на

(() => this.props.resetPatient(patient, index))();

Но в этом нет необходимости.

person Jaspreet Singh    schedule 23.09.2019