如何通过反应将数据从对话框发送回父容器?

Cod*_*ver 5 javascript state dialog reactjs react-props

我有一个react-big-calendar(父容器),我还有一个选择,根据这个选择(医生姓名)获取日历的事件,当我点击它时我有一个按钮,对话框将be 出现(另一个组件),在这个对话框中,我有一个表单可以在选择后添加一个事件,当我发布我的 API 时,我将它保存在本地存储中,但是在刷新后添加的事件没有出现在我的日历上页面并重新选择医生姓名。但我想,当我点击保存按钮时,会直接添加到日历上,并且会出现在日历上。

我的日历代码是:

   import Popup from './Popup';
export default class Calendar extends Component {
constructor(props){
    super(props);
    this.state = {
      events : [],
      open: false,
}}
componentDidMount = () => {
    fetch(process.env.REACT_APP_API_BACKEND_YET+'get_liste_praticien.php')
      .then(Response => Response.json())
      .then(data => {
        this.setState ({ praticiens : data })
        localStorage.setItem('Liste de praticiens ', JSON.stringify(this.state.praticiens))
    })
}
fetchData = (nom,identifiant_user) => {
    this.setState({
      events: [],
      evtStorage:[],
      prevEvents:[], 
      evtBackend:[]
    })
      fetch(process.env.REACT_APP_API_BACKEND+'get_liste_planning')
        .then(Response => Response.json())
        .then(data => {
          let evts = data.ListeResult;
          for (let i = 0; i < evts.length; i++) {
            evts[i].start = moment(evts[i].start).toDate();
            evts[i].end = moment(evts[i].end).toDate();
           if(evts[i].typeplanning === '0') this.setState({isConges:true})
            this.state.events.push(evts[i])
          }                   
          this.setState({
            evtBackend: evts,
            events:  evts
          })
          localStorage.setItem("Liste de planning de " + nom, JSON.stringify(this.state.events));
        }) 
        const evtCached1 = JSON.parse(localStorage.getItem('Liste récente de planning de ' + nom));
        if(evtCached1 !== null) {
          for (let j = 0; j < evtCached1.length; j++) {
            evtCached1[j].start = moment(evtCached1[j].start).toDate();
            evtCached1[j].end = moment(evtCached1[j].end).toDate();
            if(evtCached1[j].typeplanning === '0') this.setState({isConges:true})
            this.state.events.push(evtCached1[j]);
          } 
          this.setState({
            events:this.state.events,
          });
          localStorage.removeItem("Liste de planning de " + nom);
        }}
// For the select
handlePraticienChange = id_user => {
    this.setState({ 
      openPopupAjout: true,
      id_user: id_user 
    },() => {
      this.state.praticiens.map((praticien)=> {
          if(this.state.id_user === praticien.id_user){
            this.setState ({ nom_user: praticien.nom_user})
           this.fetchData(praticien.nom_user, praticien.identifiant_user);
          }
      })
      }
    );
  }
// for the popup
 ModalAjoutb = (ref) => {
    if (ref) {
      this.ajoutb = ref.handleAjouterb;
    } else {
      this.ajoutb = null;
    }
  }
render() {

    return (
<div>
    <button className="bp3-button bp3-icon-add-to-artifact .bp3-fill" tabIndex="0" onClick={() => this.ajoutb(this.state.id_user, this.state.events)}>Add event</button>
    <Select  onChange={this.handlePraticienChange} value={this.state.id_user}>
        {this.state.praticiens.map((praticien) =>
            <Option key={praticien.id_user} value={praticien.id_user}>{praticien.nom_user}</Option>
        )}
    </Select>
    <DragAndDropCalendar
        selectable
        localizer={localizer}
        events={this.state.events} 
        views={['month','week','day']}
        defaultView="week"
        culture = 'fr'
    />
    <Popup ref={this.ModalAjoutb} id_user={this.state.id_user} events={this.state.events} />
</div>
);
}}
Run Code Online (Sandbox Code Playgroud)

我的对话框代码是:

export default class Popup extends Component {
constructor(props){
    super(props);
    this.state = {
      events : [],
}}
handleAjouterb = (id_user) => {
    this.setState({
      openPopupAjout: true,
      id_user,
    }, () => {
        this.fetchingPopup(this.state.id_user, this.state.identifiant_user, this.state.nom_user)
    });
  }
fetchingPopup = (id_user, identifiant_user, nom_user) =>{
    const praticiensCached = JSON.parse(localStorage.getItem('Liste de praticiens '));
    for (let j = 0; j < praticiensCached.length; j++) {
      if(id_user === praticiensCached[j].id_user){
        identifiant_user = praticiensCached[j].identifiant_user;
        this.setState ({ nom_user: praticiensCached[j].nom_user })
    }
}
handleValider = event => {
    event.preventDefault();
    const praticiensCached = JSON.parse(localStorage.getItem('Liste de praticiens '));
    for (let j = 0; j < praticiensCached.length; j++) {
      if(this.state.id_user === praticiensCached[j].id_user)
        this.state.identifiant_user = praticiensCached[j].identifiant_user;
    }

      const formData = new FormData();

      formData.append('identifiant_user', this.state.identifiant_user);
      formData.append('heuredebut', this.state.tranchesC[0].startC);
      formData.append('heurefin', this.state.tranchesC[0].endC);
      formData.append('libelleconge', this.state.libelle);
      axios({
        method: 'post',
        url: process.env.REACT_APP_API_BACKEND+'add_event_docteur',
        data: formData,
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        }
      })
      .then(() => {
        fetch(process.env.REACT_APP_API_BACKEND+'get_liste_planning/start='+moment().startOf('isoweek').subtract(14,'days').toJSON()+'&end='+moment().endOf('isoweek').add(2,'months').toJSON()+'&identifiant_user='+this.state.identifiant_user)
          .then(Response => Response.json())
          .then(data => {
            let evts = data.ListeResult;
            for (let i = 0; i < evts.length; i++) {
              evts[i].start = moment(evts[i].start).toDate();
              evts[i].end = moment(evts[i].end).toDate();
              this.state.events.push(evts[i])
            }                   
            this.setState({
              events:  this.state.events
            }, ()=> {
              localStorage.setItem('Liste récente de planning de ' + this.state.nom_user, JSON.stringify(this.state.events));
              localStorage.removeItem("Liste de planning de " + this.state.nom_user);
              localStorage.setItem("Liste de planning de " + this.state.nom_user, JSON.stringify(this.state.events));
            })
          })
       })
}

render() {

    return (
<div>
    <Dialog
        icon="application"
        onClose={this.handleClose}
        title="Organisation des plannings du docteur"
        {...this.state}
        isOpen={this.state.openPopupAjout}>
           <Input id="libelle" style={{ width: '480px' }} value={this.state.libelle} onChange={this.handleInputChange('libelle')}/>       
            <label className="pt-label .modifier"><strong>Date</strong></label>
            <LocaleProvider locale={fr_FR}>
                <RangePicker id="date" name= "date"  locale="fr" placeholder={["Date de début","Date de fin"]} separator="-" onChange={this.handleDateCChange}
                    value={this.state.dateIC} format="DD/MM/YYYY" allowClear={false}/> 
            </LocaleProvider>
            <label className="pt-label .modifier"> <strong>Heure de début</strong></label>
            <Time value={el.startC} onChange={time => this.handleKeyboardStartCChange(i, time)} style={heure} disableUnderline={true} inputComponent={TextMaskCustom}
                    endAdornment={ <InputAdornment position="end" style={{opacity:'0.4'}}> <IconButton   onClick={() => this.openDialogC(i, el.startC, "startC")}><i  style={{fontSize:'18px'}} className="zmdi zmdi-alarm" /></IconButton>  </InputAdornment>}
            />
            <label className="pt-label .modifier"> <strong>Heure de fin</strong></label>
            <Time value={el.endC} onChange={time => this.handleKeyboardEndCChange(i, time)} style={heure} disableUnderline={true} inputComponent={TextMaskCustom}
                    endAdornment={ <InputAdornment position="end" style={{opacity:'0.4'}}> <IconButton  onClick={() => this.openDialogC(i, el.endC, "endC")}><i  style={{fontSize:'18px'}} className="zmdi zmdi-alarm" /></IconButton></InputAdornment> }/>

            <Clock maxWidth="xs" open={this.state.isOpenC} onBackdropClick={this.closeDialogC}>
            <TimePicker  mode="24h" value={this.createDateFromTextValueC(this.state.datePickerValueC)} onChange={this.handleDialogCChange}/>
            <DialogActions> <ButtonOk onClick={this.closeDialogC} color="primary"> Ok </ButtonOk></DialogActions>
            </Clock>
                <AnchorButton style={{display:'inline-block'}} intent={Intent.SUCCESS} onClick={this.handleValider}>Valider</AnchorButton>

</div>
);
}}
Run Code Online (Sandbox Code Playgroud)

我想刷新我的事件列表,并在弹出窗口的发布表单之后而不是在刷新页面之后将我的事件添加到日历上,我将重新选择医生。

我该如何解决?

Ten*_*ter 2

不要在您的状态中保存事件,在 Popup 中直接从 props 访问事件。

\n

在您的日历中,创建一个将更新状态的函数。

\n
updateEvents = (events, callback = () => {}) => {\n  this.setState(\n    {\n      events\n    },\n    callback\n  );\n};\n\n<Popup updateEvents={this.updateEvents} ref={this.ModalAjoutb} id_user={this.state.id_user} events={this.state.events} />\n
Run Code Online (Sandbox Code Playgroud)\n

弹出窗口

\n
export default class Popup extends Component {\n  constructor(props) {\n    super(props);\n  }\n\n  handleAjouterb = id_user => {\n    this.setState(\n      {\n        openPopupAjout: true,\n        id_user\n      },\n      () => {\n        this.fetchingPopup(\n          this.state.id_user,\n          this.state.identifiant_user,\n          this.state.nom_user\n        );\n      }\n    );\n  };\n  fetchingPopup = (id_user, identifiant_user, nom_user) => {\n    const praticiensCached = JSON.parse(\n      localStorage.getItem('Liste de praticiens ')\n    );\n    for (let j = 0; j < praticiensCached.length; j++) {\n      if (id_user === praticiensCached[j].id_user) {\n        identifiant_user = praticiensCached[j].identifiant_user;\n        this.setState({ nom_user: praticiensCached[j].nom_user });\n      }\n    }\n    handleValider = event => {\n      event.preventDefault();\n      const praticiensCached = JSON.parse(\n        localStorage.getItem('Liste de praticiens ')\n      );\n      for (let j = 0; j < praticiensCached.length; j++) {\n        if (this.state.id_user === praticiensCached[j].id_user)\n          this.state.identifiant_user = praticiensCached[j].identifiant_user;\n      }\n\n      const formData = new FormData();\n\n      formData.append('identifiant_user', this.state.identifiant_user);\n      formData.append('heuredebut', this.state.tranchesC[0].startC);\n      formData.append('heurefin', this.state.tranchesC[0].endC);\n      formData.append('libelleconge', this.state.libelle);\n      axios({\n        method: 'post',\n        url: process.env.REACT_APP_API_BACKEND + 'add_event_docteur',\n        data: formData,\n        headers: {\n          'Content-Type': 'application/json',\n          Accept: 'application/json'\n        }\n      }).then(() => {\n        fetch(\n          process.env.REACT_APP_API_BACKEND +\n            'get_liste_planning/start=' +\n            moment()\n              .startOf('isoweek')\n              .subtract(14, 'days')\n              .toJSON() +\n            '&end=' +\n            moment()\n              .endOf('isoweek')\n              .add(2, 'months')\n              .toJSON() +\n            '&identifiant_user=' +\n            this.state.identifiant_user\n        )\n          .then(Response => Response.json())\n          .then(data => {\n            let evts = data.ListeResult;\n            for (let i = 0; i < evts.length; i++) {\n              evts[i].start = moment(evts[i].start).toDate();\n              evts[i].end = moment(evts[i].end).toDate();\n            }\n            this.props.updateEvents(evts, () => {\n              localStorage.setItem(\n                'Liste r\xc3\xa9cente de planning de ' + this.state.nom_user,\n                JSON.stringify(evts)\n              );\n              localStorage.removeItem(\n                'Liste de planning de ' + this.state.nom_user\n              );\n              localStorage.setItem(\n                'Liste de planning de ' + this.state.nom_user,\n                JSON.stringify(evts)\n              );\n            });\n          });\n      });\n    };\n  };\n\n  render() {\n    return (\n      <div>\n        <Dialog\n          icon="application"\n          onClose={this.handleClose}\n          title="Organisation des plannings du docteur"\n          {...this.state}\n          isOpen={this.state.openPopupAjout}\n        >\n          <Input\n            id="libelle"\n            style={{ width: '480px' }}\n            value={this.state.libelle}\n            onChange={this.handleInputChange('libelle')}\n          />\n          <label className="pt-label .modifier">\n            <strong>Date</strong>\n          </label>\n          <LocaleProvider locale={fr_FR}>\n            <RangePicker\n              id="date"\n              name="date"\n              locale="fr"\n              placeholder={['Date de d\xc3\xa9but', 'Date de fin']}\n              separator="-"\n              onChange={this.handleDateCChange}\n              value={this.state.dateIC}\n              format="DD/MM/YYYY"\n              allowClear={false}\n            />\n          </LocaleProvider>\n          <label className="pt-label .modifier">\n            {' '}\n            <strong>Heure de d\xc3\xa9but</strong>\n          </label>\n          <Time\n            value={el.startC}\n            onChange={time => this.handleKeyboardStartCChange(i, time)}\n            style={heure}\n            disableUnderline={true}\n            inputComponent={TextMaskCustom}\n            endAdornment={\n              <InputAdornment position="end" style={{ opacity: '0.4' }}>\n                {' '}\n                <IconButton\n                  onClick={() => this.openDialogC(i, el.startC, 'startC')}\n                >\n                  <i style={{ fontSize: '18px' }} className="zmdi zmdi-alarm" />\n                </IconButton>{' '}\n              </InputAdornment>\n            }\n          />\n          <label className="pt-label .modifier">\n            {' '}\n            <strong>Heure de fin</strong>\n          </label>\n          <Time\n            value={el.endC}\n            onChange={time => this.handleKeyboardEndCChange(i, time)}\n            style={heure}\n            disableUnderline={true}\n            inputComponent={TextMaskCustom}\n            endAdornment={\n              <InputAdornment position="end" style={{ opacity: '0.4' }}>\n                {' '}\n                <IconButton\n                  onClick={() => this.openDialogC(i, el.endC, 'endC')}\n                >\n                  <i style={{ fontSize: '18px' }} className="zmdi zmdi-alarm" />\n                </IconButton>\n              </InputAdornment>\n            }\n          />\n          <Clock\n            maxWidth="xs"\n            open={this.state.isOpenC}\n            onBackdropClick={this.closeDialogC}\n          >\n            <TimePicker\n              mode="24h"\n              value={this.createDateFromTextValueC(this.state.datePickerValueC)}\n              onChange={this.handleDialogCChange}\n            />\n            <DialogActions>\n              {' '}\n              <ButtonOk onClick={this.closeDialogC} color="primary">\n                {' '}\n                Ok{' '}\n              </ButtonOk>\n            </DialogActions>\n          </Clock>\n          <AnchorButton\n            style={{ display: 'inline-block' }}\n            intent={Intent.SUCCESS}\n            onClick={this.handleValider}\n          >\n            Valider\n          </AnchorButton>\n      </div>\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n