-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[es_ui_shared] Fix eslint exhaustive deps rule #76392
[es_ui_shared] Fix eslint exhaustive deps rule #76392
Conversation
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
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.
Tested locally, code LGTM! Just had one question.
}); | ||
} else { | ||
didMount.current = true; | ||
if (!isMounted.current) { |
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 having trouble figuring out how we'd get into this state. Did you run into a situation where the component wasn't mounted when this function was called?
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.
Lol that's a great catch! 😊 I refactored a bit too quickly, I will put back how it was before. The intention was to not call the onUpdate
on mount as... nothing has been updated yet.
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.
EDIT: Looking at the code it is correct. So like I said, the idea is not to call the onUpdate
on component mount as there isn't any update.
In the next useEffect
the component isMounted.current
will be set to true so on the next update it will call the handler.
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.
Ah, I see. I think the use of the name isMounted
is confusing to me, particularly because it defaults to false
. The first time a hook is called is when the owner mounts, so by definition when I'm walking through a hook's "lifecycle" I begin with the mindset of it being mounted somewhere. To fix this, how about renaming the variable isInitialCall
or isFirstUpdate
, defaulting it to true
and then setting it to false
? I think this area of the code also deserves a comment explaining your intentions to the reader.
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.
particularly because it defaults to false
I must default to false. when the ref is created the component has not mounted yet. It only has mounted when a useEffect
is called (every useEffect
is called in order of appearance in the code. I learned that the hard way).
So the convention I have put in place everywhere is the same: isMounted
(because that is the React term for this and I prefer not to add another concept) defaults to false
and is set to true
in the last useEffect
in the code. So any previous useEffect will be called when mounting but the ref will still be false for them. This is exactly what we want: have a ref in our useEffects telling us if the component has mounted or not, and have some conditional logic to prevent doing certain things "on component mount". As you commented somewhere, useEffect
should have a single purpose and not one giant useEffect
(which would probably not work anyway).
This is what I shared in my "Lesson learned" here #75796
You will see around things like this
const didMount = useRef(false);
useEffect(() => {
if (didMount.current) {
// do some logic **after** the initial component mount
} else {
// the component has just mounted, nothing to do at that lifecycle
didMount.current = true;
}
}, [<deps that will influence the useEffect and get us ready for hours of debugging>]);
My convention is exactly this pattern but, as I have learned, it is much better to have a dedicated useEffect to handle this ref, and set it as last useEffect without any deps.
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 for explaining. I think some comments in the code would help explain this to others (or even our future selves).
@elasticmachine merge upstream |
@elasticmachine merge upstream |
…/kibana into fix-es-lint-exhaustive-deps-rule
…sonEditor" This reverts commit 1f9ae41.
💚 Build SucceededBuild metricsasync chunks size
page load bundle size
History
To update your PR or re-run it, just comment with: |
* master: (340 commits) [data.search.SearchSource] Remove legacy ES client APIs. (elastic#75943) [release notes] automatically retry on Github API 5xx errors (elastic#76447) [es_ui_shared] Fix eslint exhaustive deps rule (elastic#76392) [i18n] Integrate 7.9.1 Translations (elastic#76391) [APM] Update aggregations to support script sources (elastic#76429) [Security Solution] Refactor Network Top Countries to use Search Strategy (elastic#76244) Document security settings available on ESS (elastic#76513) [Ingest Manager] Add input revision to the config send to the agent (elastic#76327) [DOCS] Identifies cloud settings for Monitoring (elastic#76579) [DOCS] Identifies Cloud settings in Dev Tools (elastic#76583) [Ingest Manager] Better default value for fleet long polling timeout (elastic#76393) [data.indexPatterns] Fix broken rollup index pattern creation (elastic#76593) [Ingest Manager] Split Registry errors into Connection & Response (elastic#76558) [Security Solution] add an excess validation instead of the exact match (elastic#76472) Introduce TS incremental builds & move src/test_utils to TS project (elastic#76082) fix bad merge (elastic#76629) [Newsfeed] Ensure the version format when calling the API (elastic#76381) remove server_extensions mixin (elastic#76606) Remove legacy applications and legacy mode (elastic#75987) [Discover] Fix sidebar element focus behavior when adding / removing columns (elastic#75749) ...
…rok/new-patterns-component-use-array * 'master' of github.com:elastic/kibana: (75 commits) Remove legacy ui-apps-mixin (elastic#76604) remove unused test_utils (elastic#76528) [ML] Functional tests - add UI permission tests (elastic#76368) [APM] @ts-error -> @ts-expect-error (elastic#76492) [APM] Avoid negative offset for error marker on timeline (elastic#76638) [Reporting] rename interfaces to align with task manager integration (elastic#76716) Revert back ESO migration for alerting, added try/catch logic to avoid failing Kibana on start (elastic#76220) Test reverting "Add plugin status API (elastic#75819)" (elastic#76707) [Security Solution][Detections] Removes ML Job Settings SIEM copy and fixes link to ML app for creating custom jobs (elastic#76595) [Maps] remove region/coordinate-maps visualizations from sample data (elastic#76399) [DOCS] Dashboard-first docs refresh (elastic#76194) Updated ServiceNow description in docs and actions management UI to contains correct info (elastic#76344) [DOCS] Identifies cloud settings in reporting (elastic#76691) [Security Solution] Refactor timeline details to use search strategy (elastic#75591) es-archiver: Drop invalid index settings, support --query flag (elastic#76522) [DOCS] Identifies graph settings available on cloud (elastic#76661) Add more info about a11y tests (elastic#76045) [data.search.SearchSource] Remove legacy ES client APIs. (elastic#75943) [release notes] automatically retry on Github API 5xx errors (elastic#76447) [es_ui_shared] Fix eslint exhaustive deps rule (elastic#76392) ...
This PR fixes all the eslint disabled
"react-hooks/exhaustive-deps"
rule in the "es_ui_shared" plugin folder.There is only one left, on purpose in the
useRequest()
hook as this one is under control 😊Fixes #73970
Fixes #73971
Fixes #73972