forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] Fix VisualizationActions React component infinite…
… rerendering (elastic#177770) **Fixes:** elastic#177734 ## Summary This PR fixes `VisualizationActions` React component infinite rerendering caused by unstable hook dependencies and async state update via `useAsync`. ## Details Initial problem is described as Rule details page is not responsive and leads to page crash for rule in non-default spaces. Further investigation revealed the problem is caused by infinite React re-rendering of `VisualizationActions` component caused by a number of reasons. It's not an issue in default space because the problematic component isn't rendered at al (it looks like some discrepancy between default and non-default spaces which could be a bug as well). Besides Rule details page the problem occurs on alerts page as well. ### Promise + unstable dependencies = infinite re-render React re-renders the app each time a new state is set. It may be beneficial to memoize some intermediate results via `useMemo()`, `useCallback` and etc. These hooks accept a list of dependencies as a second parameter. Whenever a dependency changes the hook returns an updated value. If a dependency changes every render `useMemo()` doesn't give any benefit. In fact it gives a negative impact by consuming memory and burning CPU cycles. In case if a Promise involved and it's also unstable (recreated every render) it will cause infinite re-rendering. How does it work - a hook or some function returns a promise - promise result is awaited in `useEffect` + `.then()` or by using `useAsync` - after a promise resolves a new state is set (state is needed to rendered the promise result) - state update leads to a new render where the cycle repeats ### What are the typical mistakes with dependencies - Accepting an optional parameter and this parameter has a default value as an empty object or array ```ts function myHook(param = {}) { ... return useMemo(..., [param]); } ``` - Accepting a configuration object which is used as dependency ```ts function myHook(params) { ... return useMemo(..., [params]); } function MyComponent() { const result = myHook({ someOption: 'foo', }); } ``` - Returning an object without memoization (while field values could be memoized) ```ts function myHook(params) { const cb = useCallback(() => {...}, []); return { foo: cb, }; } function MyComponent() { const result = myHook(); const memoizedResult = useMemo(() => result, [result]); } ``` - Use the whole input properties object as a dependency Spreading should be used wisely. Properties spreading is definitely an [anti-pattern](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md). ```ts function MyComponent(props) { const myCallback = useCallback(() => { invokeExternalFunction({ ...props, foo: 'bar', }); }, [props]); ... } ``` ### Fixes in this PR This PR updates involved hooks to make them producing stable results (for example object or array isn't regenerated every render). (cherry picked from commit d45b8d3)
- Loading branch information
Showing
8 changed files
with
154 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.