refactor: useEffectEvent for efficient deps#23871
Conversation
5f6d137 to
71731dc
Compare
Codecov Report
@@ Coverage Diff @@
## master #23871 +/- ##
==========================================
- Coverage 68.11% 68.08% -0.03%
==========================================
Files 1938 1941 +3
Lines 74972 75020 +48
Branches 8141 8154 +13
==========================================
+ Hits 51067 51079 +12
- Misses 21826 21858 +32
- Partials 2079 2083 +4
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 6 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
|
|
||
| const handleWindowResize = useCallback(() => { | ||
| const handleWindowResize = useEffectEvent(() => { | ||
| setHeight(getSqlEditorHeight()); |
There was a problem hiding this comment.
| setHeight(getSqlEditorHeight()); | |
| setHeight(height); |
There was a problem hiding this comment.
In this approach, this doesn't need to wrap with useEffectEvent since no references needed other than setHeight.
Let me clean up with setHeight then.
There was a problem hiding this comment.
Oh, that's right. I didn't notice it was a useState 👍🏼
| }, [dispatch, queryEditor.sql, startQuery, stopQuery]); | ||
|
|
||
| const handleWindowResize = useCallback(() => { | ||
| const handleWindowResize = useEffectEvent(() => { |
There was a problem hiding this comment.
You should pass the height to the effect event. Check the Notes here.
| const handleWindowResize = useEffectEvent(() => { | |
| const handleWindowResize = useEffectEvent(height => { |
There was a problem hiding this comment.
removed handleWindowResize since no longer needed
|
This will be indeed a nice addition to React. Looking forward to it. |
SUMMARY
We often to update(add) the useEffect dependencies to fix the dependency warnings (i.e. #22974)
This work has potential performance degrade issue.
For example, #22974 updated the following useEffect dependancies.
superset/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
Lines 382 to 397 in 097f475
This means
setHeightand window event allocation can be triggered anytime handleWindowResizeWithThrottle/onBeforeUnload or/and updated.The problem is
onBeforeUnloadalso has dependancies by useCallbacksuperset/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
Lines 365 to 380 in 097f475
So whenever database is updated or latestQuery state updated, the above useEffect triggers the additional setHeight(which triggers re-rendering) and new event allocation (no memory leaked but unnecessary addEventListener/removeEventListener operation triggered)
This is common issue on react useEffect usage, so there's an official solution (useEffectEvent) is introduced.
For more detail, please check the blog link /w video clip or official proposal document
FYI: currently eslint rule of exhaustive-deps related to useEffectEvent is under experimental, this commit uses use-event-callback to avoid the warning
In addition to introduce the useEffectEvent, this commit also tune up L365-L380 to avoid the unnecessary setHeight triggered during database is updated.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A
TESTING INSTRUCTIONS
Resize sqllab editor to verify the query panel height adjusted accordingly.
ADDITIONAL INFORMATION