#Reset fetcher after submission

1 messages · Page 1 of 1 (latest)

thorn gate
#

Hello, I have a fetcher that I need to call multiple times.

That being the case, I'd like to be able to reset the fetcher so that the fetcher.type no longer is done, and instead is reset to idle.

Is there a way to do this?

deft lily
#

Why do you need to call it multiple times? Does every new call use different data?
It could be easier to help if you share more details or code fragments of your use case. 🙂

silent rain
#

Unfortunately there is no reset method on fetchers. If you call load/submit again, the fetcher state will transition again from idle => loading => idle. Remember, state is different from type. You can derive type from state and data. In fact I believe RR 6.4 gets rid of type.

|state.    |data.   |type                   |
|idle.     |null.   |init                   |
|idle.     |non null|done                   |
|submitting|*       |action/loaderSubmitting|
|loading.  |*       |actionReload/normalLoad|
spice bloom
#

Resurecting this thread since @silent rain is already on it and I found this code on the github discussion for this topic. My problem is TypeScript is complaining about the type coming from fetcher.data. It says for fetcher.data.something, something does not exist. Is there something missing from this code?
Here's the proposed useFetcherWithReset() hook:

export type FetcherWithComponentsReset<T> = FetcherWithComponents<T> & {
  reset: () => void;
};

export function useFetcherWithReset<T>(): FetcherWithComponentsReset<T> {
  const fetcher = useFetcher<T>();
  const [data, setData] = useState(fetcher.data);
  useEffect(() => {
    if (fetcher.state === "idle") {
      setData(fetcher.data);
    }
  }, [fetcher.state, fetcher.data]);
  return {
    ...fetcher,
    data: data as T,
    reset: () => setData(undefined)
  };
}

Here's what I'm trying to do with it.

const fetcher = useFetcherWithReset<typeof action>();
  const dataUri = fetcher.data?.dataUri || defaultValue;

I didn't make any changes from the provided code. Any idea how to make TypeScript happy?

graceful flame
#

Maybe TypeScript hasn't inferred the right return type for your action and you need to manually specify it

#

Can you hover over "fetcher data" in the expression "fetcher.data?.dataUri" and see what type your IDE thinks it is?

silent rain
#

You're right. Here's an updated version.

https://stackblitz.com/edit/remix-run-remix-vhgfqt?file=app%2Froutes%2F_index.tsx

export function useFetcherWithReset<T>(): FetcherWithComponentsReset<SerializeFrom<T>> {
  const fetcher = useFetcher<T>();
  const [data, setData] = useState(fetcher.data);
  useEffect(() => {
    if (fetcher.state === "idle") {
      setData(fetcher.data);
    }
  }, [fetcher.state, fetcher.data]);
  return {
    ...fetcher,
    data: data as SerializeFrom<T> | undefined,
    reset: () => setData(undefined),
  };
}
#

Remember, fetcher.data can be undefined (before load/submit and after reset)

spice bloom
#

Okay. I tried to do that and it didn't work. Now that I think about it... I might have typed SerializeForm.

graceful flame
#

What kind of data is your action returning. Json?

graceful flame
spice bloom
#

It’s just returning an object with one property with a string value.

#

It’s all happy now

#

Thank you

silent rain
#

Ok, good to hear