Home > Enterprise >  How to lift up DatePicker(@mui) value to a parent component?
How to lift up DatePicker(@mui) value to a parent component?

Time:03-30

I've just started to study ReactJS and want to write a simple app with DatePicker. My idea is to create a component, called, DateTimeSelector (Child component), with DatePicker, and to call DateTimeSelector in App.js (Parent component) multiple times (at least, to specify start and end date).

And I'm stuck at lifting up state from child to parent component.

Here is my code:

1) DateTimeSelector (Child) component

...

export default function DateTimeSelector(props) {

    const [value, setValue] = React.useState(null);

    function onChangeHandler(newValue) {
        setValue(newValue);
        console.log(newValue);
    }

    return (
        <LocalizationProvider dateAdapter={AdapterDateFns}>
        <DatePicker label={props.text}
          value={value}
          onChange={onChangeHandler}
          renderInput={(params) => <TextField {...params} />}
        />
      </LocalizationProvider>
    );

}

2) Main (Parent) component

Within this component I want to output values of each DateTimeSelector component in console and, for example, print these values in .

Now in console I see only values from my DateTimeSelector component, but not from the parent.

So, my question is how to pass date values from DatePickers to parent component as the state variables: startDate and endDate?

...

function App() {

  const [startDate, setStartDate] = React.useState(null);
  const [endDate, setEndDate] = React.useState(null);

  function startDateChangeHandler(value) {
      setStartDate(value);
      console.log(startDate);
  }

  function endDateChangeHandler(value) {
      setEndDate(value);
      console.log(endDate);
  }

  return (
    <Container>
      <Grid container spacing={2}>
      <Grid item xs={3}>
        <div>
          <DateTimeSelector text='Start Date' 
                            value={startDate}
                            onChange={startDateChangeHandler} />
        </div>
        <div>
          <DateTimeSelector text='End Date'
                            value={endDate}
                            onChange={endDateChangeHandler}/>
        </div>
      </Grid>
      <Grid item xs={9}>
        <div><p>Start Date: {startDate ?  JSON.stringify(startDate) : null}</p>
             <p>End Date: {endDate ?  JSON.stringify(endDate) : null}</p>
        </div>
      </Grid>
    </Grid>
     </Container>
  );
}

export default App;

CodePudding user response:

no need state in the child. you can refer this code link

CodePudding user response:

I found the solution! Thanks for the advise not to have state in Child!

DateTimeSelector (Child)

export default function DateTimeSelector(props) {

    function onChangeHandler(date) {
        props.onChange(date);
    }

    return (
        <LocalizationProvider dateAdapter={AdapterDateFns}>
        <DatePicker label={props.text}
          value={props.date}
          onChange={onChangeHandler}
          renderInput={(params) => <TextField {...params} />}
        />
      </LocalizationProvider>
    );

}

App (Parent)

function App() {

  const [startDate, setStartDate] = React.useState(null);
  const [endDate, setEndDate] = React.useState(null);
  
  function startDateChangeHandler(date) {
      console.log('startDateChangeHandler');
      setStartDate(date);
      console.log(startDate);
  }

  function endDateChangeHandler(date) {
    console.log('endDateChangeHandler');
    setStartDate(date);
    console.log(endDate);
}

  return (
    <Container>
      <Grid container spacing={2}>
      <Grid item xs={3}>
        <div>
          <DateTimeSelector text='Start Date' 
                            date={startDate}
                            onChange={startDateChangeHandler} />
        </div>
        <div>
          <DateTimeSelector text='End Date'
                            date={endDate}
                            onChange={endDateChangeHandler}/>
        </div>
      </Grid>
      <Grid item xs={9}>
        <div>
          <p id='start_date'>Start Date: {startDate ?  JSON.stringify(startDate) : null}</p>
          <p id='end_date'>End Date: {endDate ?  JSON.stringify(endDate) : null}</p>
        </div>
      </Grid>
    </Grid>
     
     <Button variant="contained">Hello World!</Button>
     </Container>
  );
}
  • Related