-
Notifications
You must be signed in to change notification settings - Fork 137
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
Move logic to redux #507
Move logic to redux #507
Conversation
Wonderful, I always wanted to move to using thunk and actions, but could never get it right. Redux toolkit way of doing this was a bit confusing to me. Let me study your PR. |
Pros: - [Strongly recomended](https://redux.js.org/style-guide/style-guide#put-as-much-logic-as-possible-in-reducers) - Easier testing - Easier mocking of libraries and use of storybook - More flexible notification handling
5784fd3
to
a529132
Compare
My idea is to pass const someAsyncAction = createAsyncThunk('action/requestStatus', async (arg) => {
const { auth, payload } = arg;
const { id } = payload
const response = await doSomeethingById(auth, id);
return response;
});
/**
* Dispatching async actions
*
* When dispatching async actions with auth0,
* wrap the `payload` within `arg` parameter of the `payloadCreator` function.
*
* Example:
*/
const auth = useAuth()
const payload = { id: '0' }
const arg = {
auth: auth,
payload: payload
}
dispatch(someAsyncAction(arg)) |
I've never worked with thunk, so I'll hold off on reviewing till I get a good understanding of it. But essentially, the idea here is to abstract away both the authentication and API calls to reducers, right @mradenovic ? |
Yes. It is easier for maintenance, and if decided to change something in the logic (i.e. replace auth0 with Firebase auth ), it can be done in one place. |
We should centralise this into redux. Our components would then look so much more clean. Can you also add one more where there will be a payload? |
I am working on next itteration. I managed to completely move auth to async thunk with hook. It has some quirks though. I also discovered some bug. It looks like current delete functionality doesn't update myQueues. It worked before #504 was applied, but that is because that bug was constantly fetchin data from the server. |
Interesting, how did you do that? I did find somewhere a custom middleware+local storage for token solution, but didn't like it. Yes, I also noticed this. As a side effect of #504 it was getting updated before. But this issue would go away when we move to redux and have the delete queue action that would update the global store, I guess? |
One more curriosity here: The server does not check if user is authenticated. If I send a request from client as // api/axios-alt.js
// to test, change line 16 declaration
const accessToken = false //auth.isAuthenticated
? await auth.getAccessTokenSilently({ audience: 'https://devbackend.simplq.me/v1' })
: 'anonymous'; |
Yes, this in in my list. I am thinking of doing this: When a user is not logged in, we create a UUID and store it in the local storage. Instead of Then post sign in, we call a backend API that would transfer ownerships from this ID to the signed in user, if such an ID exists in local storage. What do you think? Ideally there should be some anonymous login, which would generate short lived tokens, but this setup looks good enough for me. |
I don't know much about handling users on the backend. I usually use ready made solutions when I need one 🤣 Firebase auth has all of that solved and that was what I used in the past for prototyping. |
const { isAuthenticated } = useAuth0(); | ||
const dispatch = useDispatch(); | ||
const queues = useSelector(selectQueues); | ||
const fetchQueues = useCallback(useFetchQueues(), []); |
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.
Use useCallback()
only if the action is going to be dispatched in useEffect()
.
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.
Still understanding the change, thanks!
The user is already on Home page. There is no need to redirect.
* const fetchQueues = useFetchQueues() | ||
*/ | ||
const useFetchQueues = () => { | ||
const auth = useAuth(); |
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 is pretty smart ✌️
if (!auth || !auth.isAuthenticated) { | ||
return { queues: [] }; | ||
} |
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.
Do we need !auth
here? We should also add auth. isLoading
here, I think.
Also leave this comment:
// TODO: Remove `!auth.isAuthenticated` after resolving https://github.com/SimplQ/simplQ-frontend/issues/477
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.
We definitely do not need !auth
, it is guaranteed to be there by the hook. There was a lot of copy-paste happening so there will be a lot to remove 😊 I haven't explored what exactly should happen when not authenticated, so that should be implemented later.
|
||
* @see ./queuesSlice | ||
* | ||
* @see https://redux-toolkit.js.org/api/createAsyncThunk#return-value |
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'll have to read this 😄
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.
@daltonfury42 where can I find deployed PR?
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'm sorry, I didn't understand the last one.
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.
@mradenovic We generate temporary preview deployments. This can be triggered by putting any label on the PR (You can see a sample here)
But due to some security limitations, this is not possible on PRs from forks.
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, I'll push to repo to see how it works.
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.
Can't wait to merge this. It will be massive. 💪
For me weekend is here, I will migrate remaining components as soon as this PR goes in.
@@ -0,0 +1,26 @@ | |||
import { createSlice } from '@reduxjs/toolkit'; |
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.
We should rename the file to userQueusSlice
, and correspondingly make changes in lines 4,5,24 and 26.. and also outside usages.
history.push(`/pageNotFound/queueName=${queueName}`); | ||
return rejectWithValue({ message: `Queue ${queueName} does not exist, try again...` }); |
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.
👀
loading={!queueStatus} | ||
> | ||
<QueueStats queueStatus={queueStatusResponse} /> | ||
<QueueStats queueStatus={queueStatus} /> |
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 won't work, we would have to check for empty object. 🤔
An isLoading flag might be better, as you were implementing before?
These kind of glitches we can fix in a follow up PR as well.
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.
All pending',
fulfilled, and
rejected` should be handled in reducers. It can be done later.
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.
code looks much cleaner now
I suggest we continue the conversation at #522. |
Pros:
Resolves #517
Resolves #518