informed icon indicating copy to clipboard operation
informed copied to clipboard

Resetting a multi-step form causes an error

Open drpayyne opened this issue 3 years ago • 12 comments

Describe the bug Trying to reset a multi-step form causes the error - Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. asField/forwardRef<@webpack-internal:///./node_modules/informed/dist/esm/index.js:2097:29

To Reproduce

https://codesandbox.io/embed/informed-multistep-reset-weeyx

drpayyne avatar Jan 27 '22 10:01 drpayyne

Leaving the code here in case the sandbox gets reset as I'm not familiar with it

import "./styles.css";
import { Form, Multistep, Input, useMultistepApi, useFormApi } from "informed";
import { useCallback } from "react";

const StepOne = () => {
  const { next } = useMultistepApi();

  return (
    <Multistep.Step step="1" next="2">
      <Input field="one" initialValue="1" />
      <button onClick={next}>Next</button>
    </Multistep.Step>
  );
};

const StepTwo = () => {
  const { back, next } = useMultistepApi();

  return (
    <Multistep.Step step="2" next="3" previous="1">
      <button onClick={back}>Back</button>
      <Input field="two" initialValue="2" />
      <button onClick={next}>Next</button>
    </Multistep.Step>
  );
};

const StepThree = () => {
  const { back, next } = useMultistepApi();
  const { reset } = useFormApi();

  const goToStart = useCallback(() => {
    reset();
    next();
  }, [reset, next]);

  return (
    <Multistep.Step step="3" next="1" previous="2">
      <button onClick={back}>Back</button>
      <Input field="three" initialValue="3" />
      <button onClick={goToStart}>Next</button>
    </Multistep.Step>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Form>
        <Multistep initialStep="1">
          <StepOne />
          <StepTwo />
          <StepThree />
        </Multistep>
      </Form>
    </div>
  );
}

drpayyne avatar Jan 27 '22 10:01 drpayyne

Please note that I'm using one version earlier than the latest. Basically I have a multistep form which can loop in step flow until the user decided not to. So I'd like reset the form every time the user finishes the last step.

drpayyne avatar Jan 27 '22 10:01 drpayyne

Hi @joepuzzo - just bumping this up in case you've missed it. Please take a look at this if you can, thank you!

drpayyne avatar Feb 10 '22 16:02 drpayyne

Hey sorry I totally did miss this. Will look into it!

joepuzzo avatar Feb 10 '22 16:02 joepuzzo

Ok soo I need time to think about this because technically you are trying to perform reset on fields that are not on screen so that is an issue

joepuzzo avatar Feb 10 '22 19:02 joepuzzo

@joepuzzo thanks for looking into this! Yeah I realized that too. I realize that it's technically not possible, so would probably need refactoring of how multi-step works and renders I assume?

drpayyne avatar Feb 11 '22 10:02 drpayyne

@joepuzzo if the problem is that the fields aren't currently in the DOM, can we rather show/hide the fields using CSS? that way all the fields are in the DOM and we can reset them as required. Do you see any pitfalls in changing the way multistep works to this way?

drpayyne avatar Feb 15 '22 21:02 drpayyne

informed is not a dom library it is a react library. This would not work in native.

joepuzzo avatar Feb 15 '22 21:02 joepuzzo

Ah right, my bad. Is a solution even technically possible without doing a refactor of how multistep works in that case @joepuzzo?

drpayyne avatar Feb 15 '22 21:02 drpayyne

It may require significant code changes. I would reccomend maybe creating your own multistep for now and I will think on this.

joepuzzo avatar Feb 15 '22 22:02 joepuzzo

Thanks for your response, appreciate it.

drpayyne avatar Feb 15 '22 22:02 drpayyne