fullstack
fullstack

Reputation: 834

Update parent component from child when child unmounts

I have a parent component with array of children that displays the next children every time the next button in clicked.

const SqlSchema = () => {
  const [activeStep, setActiveStep] = useState(0);
  const [stepResponse, setStepResponse] = useState();
  const steps = ['Connect', 'Define tables', 'Define hierarchy', 'Finish']; 

  const getStepContent = (step) => {
    switch (step) {
      case 0:
        return <ConnectToDB onSubmit={setStepResponse} />;
      case 1:
        return <DefineTables data={stepResponse.data} onSubmit={setStepResponse} />;
      case 2:
        return <DefineHierarchy data={stepResponse.data} onSubmit={setStepResponse} />;
      case 3:
          return <Finish data={stepResponse.data} onSubmit={setStepResponse} />
    }
  };

  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };

  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };

  return (
     <Stepper activeStep={activeStep}>
        {steps.map(label => (
            <Step key={label}>
              <StepLabel>{label}</StepLabel>
            </Step>
        ))}
      </Stepper>

      <div>
        {activeStep === steps.length ? (
          <Typography className={classes.instructions}>
            All steps completed - you&apos;re finished
          </Typography>
        ) : (
          <div>
            <Typography>{getStepContent(activeStep)}</Typography>
            <div>
              <Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
                Back
              </Button>
              <Button onClick={handleNext} className={classes.button}>
                {activeStep === steps.length - 1 ? 'Finish' : 'Next'}
              </Button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

every child gets data and onSubmit props, and manage own state based on the data prop. I want to execute the onSubmit prop with the child state when next button is clicked, and update the parent data with the child state and send it to the next child. I tried to do something like this in every child:

const [value, setValue] = useState(props.data);
useEffect(() => {
  return () => props.onSubmit(value);
}, []);

but I it sends the initial state instead of the updated state. if I add the "value" to the dependencies array in useEffect the onSubmit would be called on every setValue, and I don't want that. is there a way to get the updated state from the child only when the "next" button is clicked in the parent?

Upvotes: 1

Views: 515

Answers (1)

thedude
thedude

Reputation: 9812

I have to say this seems like a strange design choice, but you could use a ref to keep track of the current value:

const [value, setValue] = useState(props.data);
const valueRef = useRef(value)

useEffect(() => {
    valueRef.current = value
}, [value])

useEffect(() => {
  return () => props.onSubmit(valueRef.current);
}, []);

Upvotes: 1

Related Questions