-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[dashboard] lint warnings: NewProject.tsx #8995
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
[dashboard] lint warnings: NewProject.tsx #8995
Conversation
To be used for anchor tags that should've been buttons because they don't really bring the user to any new location.
@jankeromnes this is the new #8842 🤞 |
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.
Hi @trumbitta, many thanks for improving Gitpod! 🔥 (and also for your patience on our code reviews 😇)
I really like most of the changes proposed here, and think they are quite valuable improvements. 👍
But, since I'm a bit uncertain about a few items, I've left some questions/remarks in-line. Please take a look at them when you have some time, I'm looking forward to your thoughts on these.
@@ -42,6 +42,29 @@ export default function NewProject() { | |||
|
|||
const [authProviders, setAuthProviders] = useState<AuthProviderInfo[]>([]); | |||
|
|||
const updateReposInAccounts = useCallback( |
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.
Is it really necessary to use useCallback
here? I believe we haven't used it elsewhere in the dashboard yet, and if I understand it correctly, calling updateReposInAccounts
from the Effect
with the dependency selectedProviderHost
already ensures that we call it only once every time the dependency changes.
I think I'd prefer not using this feature here, to limit the "magic" in our code. What do you think? 🙂
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.
Oh it was actually a cascading effect 🙂
- Without the
useCallback
, we have this linting warning: "The 'updateReposInAccounts' function makes the dependencies of useEffect Hook (at line 203) change on every render. To fix this, wrap the definition of 'updateReposInAccounts' in its own useCallback() Hook" - Leaving
updateReposInAccounts
out of the dependencies of thatuseEffect
to silence the previous warning, we have this other warning: "React Hook useEffect has a missing dependency: 'updateReposInAccounts'. Either include it or remove the dependency array." - Removing the dependency array altogether to silence the previous warning, of course makes the hook execute on every render, while keeping it empty generates the linting warning about not having empty dependency arrays when we are using some dependencies inside the hook.
The only alternative seems to be silencing the ESLint rule for this line, but as long as the code still works as intended I'd rather follow the lead of the linting rules and move on.
Let me know what you want me to do!
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.
If I'm not mistaken, you've already added the updateReposInAccounts
closure as a dependency to the useEffect
. Is that not enough to resolve the warning? (I.e. without needing the extra useCallback
?)
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.
Or, actually I really don't like this pattern of implementing functions that are only called once (EDIT: to clarify, this is a pre-existing problem from before your Pull Request, not something you did here). What about moving all the updateReposInAccounts
code back inline into the useEffect
? (Maybe as an in-line async function if needed.)
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.
What about moving all the updateReposInAccounts code back inline into the useEffect? (Maybe as an in-line async function if needed.)
Oh that's also my usual first move 🤝 but in this case updateReposInAccounts
is also used elsewhere outside the useEffect
.
Avoidable? Probably yes, but I think it will come with future refactorings 🔮
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.
If I'm not mistaken, you've already added the
updateReposInAccounts
closure as a dependency to theuseEffect
. Is that not enough to resolve the warning? (I.e. without needing the extrauseCallback
?)
Yes, but we have another warning :D look at the first of my bullet points above:
Without the useCallback, we have this linting warning: "The 'updateReposInAccounts' function makes the dependencies of useEffect Hook (at line 203) change on every render. To fix this, wrap the definition of 'updateReposInAccounts' in its own useCallback() Hook"
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's because without useCallback
the function gets created on every render, and that triggers the dependency array of the useEffect
@@ -69,7 +92,7 @@ export default function NewProject() { | |||
window.history.replaceState({}, "", window.location.pathname); | |||
setSelectedTeamOrUser(user); | |||
} | |||
}, []); | |||
}, [location.search, teams, user]); |
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 not 100% sure whether this change makes sense:
- Currently, we only call this effect once, and we immediately "consume" the search parameter if found (i.e. if you visit
/new?team=1234
, we immediately select team1234
and overwrite the URL to/new
without the query parameter). This means that, if we call this code multiple times, only the first time can have any effect. - Calling it again if
location.search
changes sort of makes sense, but can it really happen thatlocation.search
changes without a reload? (I guess it could happen if we have something like<Link to="/new?team=1234"/>
🤔) - Can
teams
oruser
really change here? Ifteams
oruser
can be something unexpected, I guess we'd need to check for that in the beginning of the effect, and return early if the values are unexpected (e.g. undefined or empty array?)
All in all, since this code currently seems to work in all cases, I'm a bit hesitant to change the effect logic 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.
I totally get it: this is a classic situation and it happens frequently when you start paying attention to ESLint rules.
My current stance about it, as you can infer from the proposed changes, is to just let ESLint do its thing and use its auto-fix feature: since the resulting code is basically always equivalent to what it was before the auto-fix, the auto-fixed dependency array quickly becomes like an implementation detail of sorts, I'm positive that ESLint has my back, and I can focus on the real features I need to work on.
Again, let me know what you want me to do :)
These are decisions I'm going to respect in all the future PRs about the linting warnings ✅
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.
Thanks! I generally agree with you, but I believe I had one bad experience where I just followed ESLint and it broke my component 😬 (or, maybe the bug was my fault and I now wrongly blame ESLint for it). I guess this calls for more testing. 👀
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 think it happened to me once!
I don't remember the specifics but like you said turns out it was my "fault" meaning I then applied "more React" to the problem (IIRC more composition and maybe a custom hook 🤔 ) and that fixed both the warning and the bug 🐞
@@ -166,30 +213,10 @@ export default function NewProject() { | |||
await getGitpodService().server.triggerPrebuild(project.id, null); | |||
})(); | |||
} | |||
}, [project, sourceOfConfig]); | |||
}, [guessedConfigString, project, sourceOfConfig]); |
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.
Reading the code, I think depending on guessedConfigString
in addition to sourceOfConfig
has the same effect. No objection here if it makes the linter happy. 🙂
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.
Yup, same reasoning as in https://github.com/gitpod-io/gitpod/pull/8995/files#r839619341
}, | ||
"[typescript]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode", | ||
"editor.formatOnSave": true |
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.
Thank you for this ❤️ I've been wanting to have this team-wide for a long time.
🎶 And we're back! 🎶 Welcome to this new episode of "Weekly pings to @jankeromnes!" 💖 Hey, any news? I see we also managed to wait long enough for the usual merge conflicts to show up 🤣 |
Hi @trumbitta! Thank you again for all these improvements, and for keeping up the pings to make sure that they get the attention they very much deserve. Most of your changes are actually fine and could be merged as is, but I'm very nervous about the effect dependency changes, so I would like to spend more time investigating & testing those specifically. (On a side note, if this had been a few separate Pull Requests, I believe I could have approved and merged most of them, while only needing more time for reviewing the effect dependency changes. 💭) |
No problem, how do you want me to split them? I can close this one and open the new ones. 🤝 |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Unstale |
Hey 😊 I think I'm going to close this and redo everything bit by bit (see #9269 and #9641), with the tiniest possible PRs while @gtsiolis drinks wine and smiles at my general direction, because the plan we hatched with @geropl on https://discord.com/channels/816244985187008514/953232219261009950/953667195089588305 didn't stand the test of time 👴 |
Description
As per https://discord.com/channels/816244985187008514/885406100436951080/953232219261009950
This fixes the first bits of lint warnings.
Specifically:
.gp-link
Tailwind class to make buttons mimic links and avoid using<a href="javascript:void(0)" ...>
projects/NewProject.tsx
Related Issue(s)
Re #3841
How to test
projects/NewProject.tsx
Release Notes
Documentation