Skip to content
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

Merged
merged 11 commits into from
Sep 3, 2020

Conversation

sebelga
Copy link
Contributor

@sebelga sebelga commented Sep 1, 2020

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

@sebelga sebelga requested a review from a team as a code owner September 1, 2020 15:23
@sebelga sebelga added release_note:skip Skip the PR/issue when compiling release notes Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.10.0 v8.0.0 labels Sep 1, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/es-ui (Team:Elasticsearch UI)

@sebelga sebelga requested a review from cjcenizal September 1, 2020 15:24
Copy link
Contributor

@cjcenizal cjcenizal left a 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) {
Copy link
Contributor

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?

Copy link
Contributor Author

@sebelga sebelga Sep 2, 2020

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@cjcenizal cjcenizal Sep 2, 2020

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.

Copy link
Contributor Author

@sebelga sebelga Sep 3, 2020

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.

Copy link
Contributor

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).

@sebelga
Copy link
Contributor Author

sebelga commented Sep 2, 2020

@elasticmachine merge upstream

@sebelga
Copy link
Contributor Author

sebelga commented Sep 2, 2020

@elasticmachine merge upstream

@sebelga sebelga requested a review from a team as a code owner September 3, 2020 06:53
@sebelga sebelga removed the request for review from a team September 3, 2020 08:50
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

async chunks size

id value diff baseline
indexManagement 1.6MB +46.0B 1.6MB
ingestPipelines 705.8KB +46.0B 705.7KB
total +92.0B

page load bundle size

id value diff baseline
esUiShared 994.2KB +514.0B 993.7KB

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@sebelga sebelga merged commit 8b085b9 into elastic:master Sep 3, 2020
@sebelga sebelga deleted the fix-es-lint-exhaustive-deps-rule branch September 3, 2020 16:45
gmmorris added a commit to gmmorris/kibana that referenced this pull request Sep 3, 2020
* 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)
  ...
jloleysens added a commit to jloleysens/kibana that referenced this pull request Sep 4, 2020
…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)
  ...
sebelga added a commit that referenced this pull request Sep 5, 2020
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:skip Skip the PR/issue when compiling release notes Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.10.0 v8.0.0
Projects
None yet
4 participants