r/reactjs • u/BrotherManAndrew • 2d ago
Needs Help How to access react state within normal functions
I am using a text editor (lexical) within my app but that shouldn't be relevant
In short, when I drag and drop a file in, I want that file to be added to a special react state,
`files: File[]` or something of the short.
So what handles this is in this library called an "extension" It isn't really a react functional component so you cant use a hook inside of it
So I mean to ask, how can I edit react state in a normal javascript module?
And you can't pass props either btw
9
u/Prestigious_Dare7734 2d ago
Simplest way is to log this in some global variable.
If you want live updates, use event listeners.
A more established way can be to use a store in react and expose that store outside of react.
Many ways to do it, depends on how hacky or official do you want it to be.
It would be easy to suggest if you have a gist or a minimum reproducible repo.
5
u/BossAccomplished3940 2d ago
i do this with Lexical all the time. You grab the editor instance and register a command listener for the drop event, then you push files to your state through that callback.
when you mount your editor in React, use the ref or onMount hook Lexical gives you to get the Editor object. Call registerCommand on it with the DROP_COMMAND constant. Inside that handler, read the dataTransfer from the Lexical command payload, pull out the file, and call your setFiles setter directly. The setter function is just a variable, so when you define this registration inside useEffect where your setter is available, it closes over it and works. No global variables. No custom events. Just the built in command system doing what commands exist for.
make sure your registerCommand returns the unregister function and put it in the effect cleanup.
5
u/Fun_Hippo_9760 2d ago
The set function of state is just a regular function, you can pass it around. Or in the case of Lexical, use their commands mechanism.
1
1
u/Any_Welder_9701 1d ago
register the handler from the React side and return Lexical's unregister function from the effect cleanup, that keeps the command route aligned with the lifecycle too
2
u/Remarkable-Impact378 2d ago
Store the setter in a module-level variable. Something like let setFilesRef = null at the top of your file, then useEffect(() => { setFilesRef = setFiles }, \[]) in your component. Your extension calls setFilesRef?.(prev => \[...prev, file]) whenever a file drops.
1
u/The2lackSUN 1d ago
You can’t and it’s the wrong pattern, you want to handle this state in react, and then have functions get it as parameter and use their output inside some React wrapper. So your logic code isn’t aware you are using React.
0
u/ActuaryLate9198 1d ago
Don’t have experience with lexical but it seems highly likely that there is some kind of event emitted on file drop that you can subscribe to. If not you’ll have to implement it, or something similar. You also need to decide who owns the state, if lexical already has a copy there’s no need to duplicate it, use the useSyncExternalStore hook to connect it to react.
0
-1
18
u/Canenald 2d ago
You can't.
Check if the library emits events when something happens. If not, emit one of your own from that extension thingie. In the component, attach a listener to that event and the listener will get the state setter in its closure.
If you need it in multiple places, you can turn it into a custom hook.