-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@uppy/react: introduce useUppyEvent #5264
Conversation
Diff output filesdiff --git a/packages/@uppy/react/lib/index.js b/packages/@uppy/react/lib/index.js
index 2739da8..951a3db 100644
--- a/packages/@uppy/react/lib/index.js
+++ b/packages/@uppy/react/lib/index.js
@@ -4,4 +4,5 @@ export { default as DragDrop } from "./DragDrop.js";
export { default as FileInput } from "./FileInput.js";
export { default as ProgressBar } from "./ProgressBar.js";
export { default as StatusBar } from "./StatusBar.js";
+export { default as useUppyEvent } from "./useUppyEvent.js";
export { default as useUppyState } from "./useUppyState.js"; |
Not sure about mixing state (like assemblyResults) into an event hook. State seems to me like something that should instead be exposed in useUppyEvent(uppy, 'transloadit:result', (r) => console.log('done', r)), |
I agree and I would not have done that if Uppy holds everything in state, but in the case of events that's not always the case, yet you do need those event results to be stateful when building a UI. The reason why only doing your proposal is not ideal is because you have to manually type everything again: const [transloaditResult, setTransloaditResult] = useState<UppyEventMap<M,B>['transloadit:result'] | []>([])
useUppyEvent(uppy, 'transloadit:result', setTransloaditResult), Both my current design and this one don't feel quite right. But at least the current design takes away most complexity. |
maybe we should instead introduce some new state then, where it makes sense? something like I think having state stored inside the event hook could lead to unnecessary performance degradation. for example if someone |
If you want to subscribe to progress, you want to re-render too, that's kind of the point. If you mean to showcase only using the callback instead of the returned state, then it's most likely because you use some stateful callback from a parent component, which means the parent and child are re-rendered. Again, that would be intended as you do something stateful in the parent UI.
Uppy core has no knowledge of transloadit specific state so the types in core can't know this. We could try to populate the state modules and interface merging, but that's a very different approach and it simply moves the problem: now you move the stale state from |
Often when subcribing to events that happen very frequently, one wants to throttle/debounce these events before updating the UI (updating state), because else there would be too many re-renders, causing slowdowns. I can think of events like |
All progress events are already throttled by us. Events like |
to illustrate the problem: if someone wants to |
That example doesn't make sense because you should never do I think you're thinking about it the wrong way, when you access state (one way or another) it's because you need it because your UI is stateful. There is no use case where it isn't stateful, then you simply don't use it at all. also for your example you probably want |
yes, maybe the |
So is this good to go or are there concrete requested changes? |
Lgtm |
| Package | Version | Package | Version | | ------------------------- | ------- | ------------------------- | ------- | | @uppy/angular | 0.7.0 | @uppy/onedrive | 4.0.0 | | @uppy/audio | 2.0.0 | @uppy/progress-bar | 4.0.0 | | @uppy/aws-s3 | 4.0.0 | @uppy/provider-views | 4.0.0 | | @uppy/aws-s3-multipart | 4.0.0 | @uppy/react | 4.0.0 | | @uppy/box | 3.0.0 | @uppy/react-native | 0.6.0 | | @uppy/companion | 5.0.0 | @uppy/redux-dev-tools | 4.0.0 | | @uppy/companion-client | 4.0.0 | @uppy/remote-sources | 2.0.0 | | @uppy/compressor | 2.0.0 | @uppy/screen-capture | 4.0.0 | | @uppy/core | 4.0.0 | @uppy/status-bar | 4.0.0 | | @uppy/dashboard | 4.0.0 | @uppy/store-default | 4.0.0 | | @uppy/drag-drop | 4.0.0 | @uppy/store-redux | 4.0.0 | | @uppy/drop-target | 3.0.0 | @uppy/svelte | 4.0.0 | | @uppy/dropbox | 4.0.0 | @uppy/thumbnail-generator | 4.0.0 | | @uppy/facebook | 4.0.0 | @uppy/transloadit | 4.0.0 | | @uppy/file-input | 4.0.0 | @uppy/tus | 4.0.0 | | @uppy/form | 4.0.0 | @uppy/unsplash | 4.0.0 | | @uppy/golden-retriever | 4.0.0 | @uppy/url | 4.0.0 | | @uppy/google-drive | 4.0.0 | @uppy/utils | 6.0.0 | | @uppy/google-photos | 0.2.0 | @uppy/vue | 2.0.0 | | @uppy/image-editor | 3.0.0 | @uppy/webcam | 4.0.0 | | @uppy/informer | 4.0.0 | @uppy/xhr-upload | 4.0.0 | | @uppy/instagram | 4.0.0 | @uppy/zoom | 3.0.0 | | @uppy/locales | 4.0.0 | uppy | 4.0.0 | - meta: Bump docker/setup-qemu-action from 3.0.0 to 3.1.0 (dependabot[bot] / #5314) - meta: Bump docker/build-push-action from 6.2.0 to 6.3.0 (dependabot[bot] / #5313) - @uppy/core: bring back resetProgress (Merlijn Vos / #5320) - docs: add note regarding `COMPANION_CLIENT_ORIGINS_REGEX` (Antoine du Hamel / #5322) - @uppy/companion: make streaming upload default to `true` (Mikael Finstad / #5315) - docs: change slug for aws docs (Merlijn Vos / #5321) - @uppy/core: export UppyOptions, UppyFile, Meta, Body (Merlijn Vos / #5319) - meta: fix React linter rules (Antoine du Hamel / #5317) - meta: enforce use of extension in import type declarations (Antoine du Hamel / #5316) - @uppy/companion: remove `oauthOrigin` (Antoine du Hamel / #5311) - docs,@uppy/companion-client: don't close socket when pausing (Mikael Finstad / #4821) - @uppy/aws-s3: fix signing on client for bucket name with dots (Antoine du Hamel / #5312) - @uppy/react: introduce useUppyEvent (Merlijn Vos / #5264) - @uppy/companion: do not list Node.js 20.12 as compatible (Antoine du Hamel / #5309) - @uppy/provider-views: `.openFolder()` - return progress indication (Evgenia Karunus / #5306) - examples,@uppy/companion: Release: uppy@3.27.3 (github-actions[bot] / #5304) - @uppy/companion: fix `TypeError` when parsing request (Antoine du Hamel / #5303)
We already have
useUppyState
(#5059) but there is a need foruseUppyEvent
. Considering the following code, which is very common when building with React and Uppy.With this PR it's as simple as
Note
One thing thing to consider is that values are stale until the next event (if that ever comes). Depending on your use case that may be expected or not. For instance, you listen for
transloadit:result
but once the user clicks "Done" in dashboard and the state is reset, you still have the stale reference to results of that event. That's why we return a "reset" function to clear the state.Another thing to know is that not all events return something. In that case it's very likely because you want to do something else when that event triggers, not have a value in state. This is possible with a third argument which is a callback.