Skip to content

Conversation

@dai-shi
Copy link
Owner

@dai-shi dai-shi commented Jun 29, 2019

It seems like the idiomatic React prefers ensuring argument referential equality on the caller end, to accepting deps in hooks.
This is going to be a big breaking change. (Actually, it's been changing back and forth.)

I made a choice to depend on use-memo-one by @alexreardon .

Feedback welcomed.

@dai-shi
Copy link
Owner Author

dai-shi commented Jun 29, 2019

Published https://www.npmjs.com/package/react-hooks-async/v/3.0.0-alpha.1

@ed-sparkes @digitaltopo
Would you try this and see how it works in your use cases?

@dai-shi dai-shi merged commit 655df9d into master Jul 2, 2019
@dai-shi dai-shi deleted the no-deps-array branch July 2, 2019 12:22
@ed-sparkes
Copy link

ed-sparkes commented Jul 5, 2019

Hmm sorry took me a while to get to this. Its not behaving the same, i removed the dependencies but now only one of my request gets called

I have my data retrieval tasks dependent on my get access token task as such

 useAsyncRun(getTokenTask) useAsyncRun(getTokenTask.result && getProjectTask) useAsyncRun(getTokenTask.result && getArtefactTask) useAsyncRun(getTokenTask.result && getJudgesTask) 

and an example of one of the tasks ...

 const getArtefactTask = useAsyncTaskAxios<AxiosResponse<Artefact[]>>( axios, { url: getArtefactUrl, headers: { Authorization: `Bearer ${getTokenTask.result}` } } ) 

Each of the subsequent tasks are axios requests to get data but none are now being fired with alpha-1

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 5, 2019

Oh no. I’d like to dig into it. Is it easy for you to build reproduction?

@ed-sparkes
Copy link

hmm ill try and put a codesandbox together

looks like i need to add an additional useMemo otherwise i get infinite calls to my getProjectsTask

so i have updated to the below but with the condition
useAsyncRun(getTokenTask.result !== null && getProjectsTask) the getProjectsTask is never run

 const getProjectArgs = useMemo(()=>{ return { url: listUrl, headers: { Authorization: `Bearer ${getTokenTask.result}` } } }, [getTokenTask.result]) const getProjectsTask = useAsyncTaskAxios<AxiosResponse<Project[]>>( axios, getProjectArgs ) useAsycRun(getTokenTask) useAsyncRun(getTokenTask.result !== null && getProjectsTask) 
@ed-sparkes
Copy link

Here is our previous code sandbox updated to use the latest version

https://codesandbox.io/s/inspiring-architecture-4gfwy

as you can see previously when the count was defined the second task ran, now it does not

@ed-sparkes
Copy link

i didnt really understand the motivation for the change as it seems there is more complexity for the consumer in having to create a separate useMemo with the dependencies rather than just pass the dependencies to your hook? Not saying it is wrong, but keen to understand the motivation for the move to ref equality over dependencies

@ed-sparkes
Copy link

In the meantime is there anyway of going back to previous alpha i tried updating package json but its still go the latest version without deps

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 5, 2019

previous alpha

https://www.npmjs.com/package/react-hooks-async/v/3.0.0-alpha.0

You want to use the exact version.

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 5, 2019

motivation

v2 APIs were not consistent, some of them require deps and some of them require memoization at consumer end.
For example, useAsyncTaskFetch didn't have deps, but useAsyncTaskAxios did have deps.

There was a reason why I added deps to some of the APIs, but long story short, I wanted to make them consistent. The question is which; deps for all APIs or memoization for all APIs.

Meanwhile, React community tends to take "memoization at consumer end" more idiomatic. (No official source, but tweets, issues, and so on.)
The practical benefit of memoization is we can rely on exhaustive-deps eslint rule. People are likely to fail providing proper deps without the rule, including myself.

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 5, 2019

Here is our previous code sandbox updated to use the latest version

Thanks for the updated version.
Somehow, you forgot to add axios instance at the first argument, which was the chage in #14.

I updated your example. https://codesandbox.io/s/frosty-feistel-1648t

@ed-sparkes
Copy link

ed-sparkes commented Jul 5, 2019

Hmm ok my real example is a little different as I am using useAsyncTask rather than the axios equiv for getting the token ...

 const getTokenTask = useAsyncTask(() => getTokenSilently()) useAsyncRun(getTokenTask) 

the geTokenSilently function returns a string
but getTokenTask result is staying undefined or null it no longer seems to be being set and as such the second task never runs.

i have tried to simulate this with a setTimeout

 const getAccessToken = useAsyncTask(async () => { await timeout(3000); return "dave"; }); useAsyncRun(getAccessToken); 

and updated the code sandbox

https://codesandbox.io/s/dank-shape-m44dh

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 5, 2019

https://codesandbox.io/s/great-browser-zhgh5

Here you go. Instead of deps, we need to useCallback/useMemo, or define the function outside of the hook. And, implementing abortability is always recommended.

If you want to useAsyncTask core hook directly, you want to learn how it's used in src/useAsyncTask*.js.

@ed-sparkes
Copy link

ah yes, that should have been obvious, i did it for the axios tasks using useMemo but nor for the other async task doh

thank you for your patience

@dai-shi
Copy link
Owner Author

dai-shi commented Jul 19, 2019

Unless there are any other concerns, I will publish v3.0.0 later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants