#hval-React
1 messages ยท Page 1 of 1 (latest)
Hello. Looking
Let me ask a colleague about this as I'm not super familiar with Redux
๐ thanks
Hello @placid crescent
Taking over for @nova sierra here
Can you share more context on what you have tried already? I don't think we have any specific guidelines around dispatching an action as it differs from integration to integration
I tried the code ahead.
I am block because of
https://reactjs.org/docs/hooks-overview.html#rules-of-hooks
Rules of Hooks
Hooks are JavaScript functions, but they impose two additional rules:
Only call Hooks at the top level. Donโt call Hooks inside loops, conditions, or nested functions.
Only call Hooks from React function components. Donโt call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks โ your own custom Hooks. Weโll learn about them in a moment.)
If you dont have specific guidelines I will find a way and I will share it with you
Gotcha.
Only call Hooks from React function components. Donโt call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks โ your own custom Hooks. Weโll learn about them in a moment.)
Technically, anything and everything that you write underPaymentElementFormfunction is considered part of a React Component right?
So I'm not clear on whats unclear here OR what the limitation is.
Can you give me an example?
Not the part from the onSubmit or the onReady (not the same context)
So I cannot call React Hooks from onSubmit
I don't think that's true.
onSubmit is still considered part of the Component itself.
As far as my understanding goes, the doc is talking about calling the hook from a function that is not part of your component hierarchy (a function that isn't a React compoenent).
In my code I have the hook error in my browser console. But maybe I am missing something
What error is that? Happy to look into it ๐
Only call Hooks at the top level. Donโt call Hooks inside loops, conditions, or nested functions.
nested function is pass to the onSubmit (it s a closure)
give me one second I will go copy this
thanks for the help btw very appreciated
NP! ๐ Good luck
So the error is :
react-dom.development.js:14906 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
Can you attach the code here so I can take a look?
the one that triggers the above error
the code is already above in the tread
(NOT with Stripe) FYI, if you need a 2nd set of eyes, I am faniliar with React/Reduc (I use it currently, with Stripe)
(NOT with Stripe) One thing that jumps out at me - Redux is for GLOABL state, not for local components. "isReady" should be entirely local:
const [isREady, setIsReady] = useState(false);
within the component
I could use a useState yes
(NOT with Stripe) those dispatches within useEffects are a pretty strong anti-pattern
But the onReady is comming from paymentElement. And I need it to disable button in another component (stripe live in a drawer with a step-wizard here, so button pay is in another component)
(NOT with Stripe) You can use the local setIsReady() inside the handler just fine
the useEffect/useRef is another topic. You can ignore this. It s a draft I try to find a way to get the ref to avoid to have to cheat with const submit = document.getElementById("payment-element").dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }))
(NOT with Stripe) the idea with Redux is for state-ful information BETWEEN unrelated or connected components, not within components- like UserID, etc
(NOT with Stripe) is the button rendered on the same screen, if not in the same component?
Apologies, got pulled away for a bit here.
Thanks @frail sleet
If you take out postPaymentConfirm(data.paymentIntent) , does it resolve the error or do you see the same error here?
postPaymentConfirm is working well
The button is on the same screen, but not the same component (both live happy together in dom)
(NOT with Stripe) perhaps work with @abstract fractal for a bit, to avoid the confusion of parallel streams
Yup, seems like there's some confusion here
Thank you @frail sleet ๐ Appreciate it
Let me summarize what I understand so far and then we can take it from there
- You're using React + Stripe + Redux with PaymentElement
- Your code is giving you the error related to react hooks as you've shared above.
- Your handleSubmit isn't causing the error (?) or is it?
Trying to narrow down on the code that's causing this behavior
- yes
- yes
For 3 I think it's
a) submit form => onSubmit
return (
<form id="payment-element" className="payment-element" onSubmit={handleSubmit} ref={stripeFormRef}>
<PaymentElement onReady={handleOnReady} />
</form>
)
b) onSubmit call handleSubmit(event) (so a closure)
c) cannot call dispatch in handleSubmit
Okay so let's try this
if you take out await dispatch(setIsReady(false)), does that fix the error?
no. Let me simplfy the code and post it again give me 2 min
(NOT) point of Redux: useDispatch is NOT async
yup
yes your right Dispatch is always syncrounous
This is working. Will try with the onReady now
well it working also. Sorry for this I think the problem was me trying to useRef on the form
(NOT with Stripe) React/Redux: if the state you are conveying (isReady) is only used between two components that only exist under a single parent, probably better to use local state in the parent.
@frail sleet @lime tangle thanks!!!!
(NOT) Yeah, that "form" isn't really what you think it is - it's a place to render an iFrame for Stripe's secure collection of info.
The button is not near of the Stripe form
I would have to make a big chain of props / event to go there unfornutally
But I agree normaly I prefrt tu use props for that kind of things
No worries! Glad that you're unblocked ๐ Good luck
Yes I know it s an iframe in dom
const handlePayButton = () => {
// @todo: find a better way, maybe with a ref, or a action
const submit = document.getElementById("payment-element").dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }))
}
@frail sleet do you have a better idea then this to trigger the form (not using the dom) ? If yes i am curious. The button is not in the parent
(NOT with Stripe) That's a pretty rough structure, that - and not a way I'd try to use useRef. If they're both visible on the same render, then they must have SOME parent in common? What are you trying to handle - only allow a payment if they have a paymentMethod?
in my not-dissimilar case, I replace the "pay now" button with a pop-up for the paymentElement if the user doesn't have a paymentMethod - when they do, I "just" render the Pay Now button
(NOT with Stripe) note my event loop in that case is pretty broad - the submit event calls the Stripe confirm, which triggers a webhook, which modifies the user object in Firebase Firestore, which has a listener attached to it in the client, which updates the user Redux object... which is what decides the Pay Now vs Collect Payment Method "switch"