-
Notifications
You must be signed in to change notification settings - Fork 1
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
fix: loading circle + tests #22
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #22 +/- ##
==========================================
+ Coverage 75.75% 76.97% +1.21%
==========================================
Files 22 22
Lines 297 317 +20
Branches 31 34 +3
==========================================
+ Hits 225 244 +19
- Misses 69 70 +1
Partials 3 3 ☔ View full report in Codecov by Sentry. |
@@ -87,7 +87,6 @@ const ReviewExamAttemptModal = ({ | |||
}, | |||
variant: 'primary', | |||
}; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Did you mean to delete this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No :(. I put it back :)
src/pages/ExamsPage/hooks.js
Outdated
@@ -105,15 +105,13 @@ export const useExamAttemptsData = () => { | |||
return { attemptsList }; | |||
}; | |||
|
|||
export const useButtonStateFromRequestStatus = (requestKey) => { | |||
export const useButtonStateFromRequestStatus = () => (requestKey) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice find!
I see how this fixes the bug, but I'm wondering about this as a solution. This new hook returns a function that, when called with a particular requestKey
gets a status from the Redux store for that request.
What benefit do you get from wrapping your hook this way; in other words, what benefit do you get from returning a function and not the actual value? There's another way to use your original hook that doesn't require returning a function (i.e. this change), and I wonder if that would be a clearer way to get the data you need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly did this because I would otherwise get an error saying that the hook needed to return a function and not the actual value, mostly due to my naivety with Redux. If there's a better way then I'd love to know it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense!
Do you still have the error? I'd be curious to see it.
Without these changes, your hook returned the status of a request based on the requestKey
argument, right? So, something like this would give you the status of the delete exam attempt request.
const status = useButtonStateFromRequestStatus(constants.RequestKeys.deleteExamAttempt))
With your current changes, you'd need to do something like this.
const getRequestStatus = useButtonStateFromRequestStatus()
const status = getRequestStatus(constants.RequestKeys.deleteExamAttempt))
Right now, the process of getting the status and passing it to the StatefulButton
is sort of like this...
- call the
useButtonStateFromRequestStatus
hook to get a function that will get the request status - call the function to get the request status
- pass the result as a
state
prop to theStatefulButton
Steps 2 and 3 are happening in the same line, but they're separate steps.
I'm wondering why you now need step 1 if your original hook already did step 2 and gave you the request status value. Couldn't you proceed onto step 3? I think taking a look at how step 3 works would be a good idea. I can see why, as written, you'd need to wrap the hook in a function, but do you need to have a function call in step 3?
Taking a look at the use of useToggle
could be helpful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so I tried reproducing the error and got a different error than I recall. npm lint spits out this error:
136:26 error React Hook "useButtonStateFromRequestStatus" is called conditionally. React Hooks must be called in the exact same order in every component render react-hooks/rules-of-hooks
So it seems like not doing the whole "returning the function" step causes us to break the rules of hooks, since the hook itself is being called within a conditional statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By reproducing this error, I assume that you did the by reverting back to the current code on main
?
Where is the conditional statement? I don't see that hook being called conditionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the "error" we're talking about is the one that would occur when the useButtonStateFromRequestStatus
hook just returns the actual value (i.e. 'pending', 'error', or '') instead of a function. The code on main currently also returns a function, not the actual value. I did, however, play with just returning the actual value in my last PR, and that is what I was trying to recreate.
Also I believe the conditional statement is this ternary operator here which is used to determine whether each button should be visible:
{attemptStatus !== constants.ExamAttemptStatus.verified
&& (
<StatefulButton
// The state of this button is updated based on the request status of the modifyExamAttempt
// api function. The change of the button's label is based on VerifyButtonProps.
state={useButtonStateFromRequestStatus(constants.RequestKeys.modifyExamAttempt)}
{...VerifyButtonProps}
variant="success"
onClick={async e => { // eslint-disable-line no-unused-vars
modifyExamAttempt(attemptId, constants.ExamAttemptActions.verify);
}}
/>
)}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I see. Where is that code coming from? I don't see it either on main
or on your branch. Do you have some uncommitted code? The code that's on main
shouldn't be throwing that error, because there's no conditional calling of the hook.
Here's what I was thinking.
You'd leave your hook with the original implementation, which is currently on main
.
export const useButtonStateFromRequestStatus = (requestKey) => {
const isPending = reduxHooks.useRequestIsPending(requestKey);
const isError = reduxHooks.useRequestError(requestKey);
return () => {
if (isPending) {
return 'pending';
} if (isError) {
return 'error';
}
return '';
};
};
This hook will return the request status of a particular request.
In src/pages/ExamsPage/components/ReviewExamAttemptModal.jsx
, your use of the hook would be the following.
const modifyExamAttemptRequestStatus = useButtonStateFromRequestStatus(constants.RequestKeys.modifyExamAttempt));
Now, you have the request status value and you can use it as the prop value for the StatefulButton
. For example, for the verified button, you'd have the following.
<StatefulButton
// The state of this button is updated based on the request status of the modifyExamAttempt
// api function. The change of the button's label is based on VerifyButtonProps.
state={modifyExamAttemptRequestStatus}
{...VerifyButtonProps}
variant="success"
onClick={async e => { // eslint-disable-line no-unused-vars
modifyExamAttempt(attemptId, constants.ExamAttemptActions.verify);
}}
/>
The hook no longer needs to return a function that has to be called by the component, and the hook is not called conditionally, so the error you posted above should not be raised.
Does that make sense? useToggle
works similarly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, I made changes similar to this and just pushed them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
This didn't work on stage when I smoke tested it, so I've fixed it up with this PR.
Screen.Recording.2024-01-11.at.2.20.12.PM.mov