teslamotors/informed

Resetting a multi-step form causes an error

drpayyne opened this issue · 11 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

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

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.

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

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

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

@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?

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

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

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

Thanks for your response, appreciate it.