ਕੀ ਤੁਸੀਂ ਕਦੇ ਅਜਿਹਾ ਟੂਲਟਿਪ (tooltip) ਬਣਾਇਆ ਹੈ ਜੋ ਉੱਪਰ-ਖੱਬੇ ਕੋਨੇ ਤੋਂ ਆਪਣੀ ਸਹੀ ਜਗ੍ਹਾ 'ਤੇ ਟੱਪਦਾ ਹੋਇਆ ਆਉਂਦਾ ਹੈ? ਜਾਂ ਕੋਈ ਮੋਡਲ (modal) ਜੋ ਸਹੀ ਆਕਾਰ ਵਿੱਚ ਆਉਣ ਤੋਂ ਪਹਿਲਾਂ ਗਲਤ ਆਕਾਰ ਵਿੱਚ ਫਲੈਸ਼ ਹੁੰਦਾ ਹੈ? ਉਹ ਇੱਕ ਸਕਿੰਟ ਤੋਂ ਵੀ ਘੱਟ ਸਮੇਂ ਵਾਲੀ ਖਰਾਬੀ ਇੱਕ ਲੇਆਉਟ ਫਲਿੱਕਰ (layout flicker) ਹੈ। ਇਹ ਉਦੋਂ ਹੁੰਦਾ ਹੈ ਜਦੋਂ React DOM ਨੂੰ ਪੜ੍ਹਦਾ ਹੈ, ਇੱਕ ਸੁਧਾਰ ਦੀ ਗਣਨਾ ਕਰਦਾ ਹੈ, ਅਤੇ state ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, ਪਰ ਬ੍ਰਾਊਜ਼ਰ ਪਹਿਲਾਂ ਹੀ ਸਕ੍ਰੀਨ 'ਤੇ ਪਿਕਸਲ ਦਿਖਾਉਣਾ ਸ਼ੁਰੂ ਕਰ ਚੁੱਕਾ ਹੁੰਦਾ ਹੈ। ਆਮ ਇਲਾਜ useEffect ਦੀ ਜਗ੍ਹਾ useLayoutEffect ਦੀ ਵਰਤੋਂ ਕਰਨਾ ਹੈ। ਇਹ ਬਦਲਾਅ ਕੰਮ ਕਰਦਾ ਹੈ, ਪਰ ਸਿਰਫ਼ ਉਦੋਂ ਹੀ ਜੇ ਤੁਸੀਂ ਸਮਝਦੇ ਹੋ ਕਿ ਬ੍ਰਾਊਜ਼ਰ ਪਾਈਪਲਾਈਨ ਦੇ ਅੰਦਰ ਹਰ ਹੁੱਕ (hook) ਬਿਲਕੁਲ ਕਦੋਂ ਚੱਲਦਾ ਹੈ।
ਬ੍ਰਾਊਜ਼ਰ ਪਾਈਪਲਾਈਨ: Render, Commit, Paint
React ਤਿੰਨ ਵੱਖ-ਵੱਖ ਪੜਾਵਾਂ ਵਿੱਚ ਇੱਕ ਕੰਪੋਨੈਂਟ ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ। render ਪੜਾਅ ਵਿੱਚ, React Virtual DOM ਬਣਾਉਂਦਾ ਹੈ—ਜਾਂ ਦੁਬਾਰਾ ਬਣਾਉਂਦਾ ਹੈ—ਅਤੇ diff ਦੀ ਗਣਨਾ ਕਰਦਾ ਹੈ। ਅਜੇ ਕੋਈ ਅਸਲ ਪਿਕਸਲ ਤਬਦੀਲੀ ਨਹੀਂ ਹੁੰਦੀ; ਇਹ ਸਿਰਫ਼ ਮੈਮੋਰੀ ਵਿੱਚ ਹੋ ਰਹੀ ਗਣਨਾ ਹੈ। ਇਸ ਤੋਂ ਬਾਅਦ commit ਪੜਾਅ ਆਉਂਦਾ ਹੈ, ਜਿੱਥੇ React ਉਹਨਾਂ ਤਬਦੀਲੀਆਂ ਨੂੰ ਅਸਲ DOM ਨੋਡਾਂ 'ਤੇ ਲਾਗੂ ਕਰਦਾ ਹੈ। ਸਟਾਈਲ ਅਪਡੇਟ ਹੁੰਦੇ ਹਨ, ਨੋਡਾਂ ਨੂੰ ਜੋੜਿਆ ਜਾਂ ਹਟਾਇਆ ਜਾਂਦਾ ਹੈ, ਅਤੇ ਟੈਕਸਟ ਬਦਲਦਾ ਹੈ।
ਫਿਰ ਬ੍ਰਾਊਜ਼ਰ ਕੰਮ ਸੰਭਾਲ ਲੈਂਦਾ ਹੈ। paint ਪੜਾਅ ਵਿੱਚ, ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਰੈਂਡਰਿੰਗ ਇੰਜਣ ਲੇਆਉਟ ਜਿਓਮੈਟਰੀ ਦੀ ਗਣਨਾ ਕਰਦਾ ਹੈ ਅਤੇ ਸਕ੍ਰੀਨ 'ਤੇ ਪਿਕਸਲ ਡਰਾਅ ਕਰਦਾ ਹੈ। ਇਹ ਕ੍ਰਮ ਸਖ਼ਤ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਪੇਂਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਲੇਆਉਟ ਪੂਰਾ ਕਰਨਾ ਪੈਂਦਾ ਹੈ, ਅਤੇ ਉਪਭੋਗਤਾ ਨੂੰ ਕੁਝ ਵੀ ਨਵਾਂ ਦਿਖਾਈ ਦੇਣ ਤੋਂ ਪਹਿਲਾਂ ਉਸਨੂੰ ਪੇਂਟਿੰਗ ਖਤਮ ਕਰਨੀ ਪੈਂਦੀ ਹੈ। commit ਅਤੇ paint ਦੇ ਵਿਚਕਾਰ ਦਾ ਅੰਤਰ ਮਿਲੀਸਕਿੰਟਾਂ ਵਿੱਚ ਮਾਪਿਆ ਜਾਂਦਾ ਹੈ, ਪਰ ਇਹ ਅਸਲ ਹੈ, ਅਤੇ ਇਹ ਉਹ ਵਿੰਡੋ ਹੈ ਜਿੱਥੇ useEffect ਅਤੇ useLayoutEffect ਵੱਖਰੇ ਹੋ ਜਾਂਦੇ ਹਨ।
useEffect ਫਲਿੱਕਰ ਕਿਉਂ ਪੈਦਾ ਕਰਦਾ ਹੈ
useEffect ਅਸਿੰਕ੍ਰੋਨਸਲੀ (asynchronously) ਚੱਲਦਾ ਹੈ, ਜੋ ਕਿ ਬ੍ਰਾਊਜ਼ਰ ਦੁਆਰਾ ਸਕ੍ਰੀਨ ਪੇਂਟ ਕਰਨ ਤੋਂ ਬਾਅਦ ਚੱਲਣ ਲਈ ਸ਼ਡਿਊਲ ਕੀਤਾ ਗਿਆ ਹੁੰਦਾ ਹੈ। DOM ਅਪਡੇਟ ਹੋ ਜਾਂਦਾ ਹੈ, ਪਿਕਸਲ ਡਰਾਅ ਕੀਤੇ ਜਾਂਦੇ ਹਨ, ਅਤੇ ਫਿਰ React ਤੁਹਾਡੇ effect ਨੂੰ ਚਲਾਉਣ ਲਈ ਵਾਪਸ ਆਉਂਦਾ ਹੈ।
ਕਲਪਨਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਇੱਕ ਬਟਨ ਦੇ ਹੇਠਾਂ ਡ੍ਰੌਪਡਾਊਨ ਮੇਨੂ ਰੈਂਡਰ ਕਰਦੇ ਹੋ। useEffect ਦੇ ਅੰਦਰ, ਤੁਸੀਂ buttonRef.current.getBoundingClientRect() ਨੂੰ ਕਾਲ ਕਰਦੇ ਹੋ, ਸਹੀ top ਅਤੇ left ਕੋਆਰਡੀਨੇਟਸ ਦੀ ਗਣਨਾ ਕਰਦੇ ਹੋ, ਅਤੇ ਉਹਨਾਂ ਨੂੰ state ਵਿੱਚ ਸਟੋਰ ਕਰਦੇ ਹੋ। ਕਿਉਂਕਿ useEffect ਪੇਂਟ ਤੋਂ ਬਾਅਦ ਚੱਲਦਾ ਹੈ, ਬ੍ਰਾਊਜ਼ਰ ਪਹਿਲਾਂ ਹੀ ਡ੍ਰੌਪਡਾਊਨ ਨੂੰ ਇਸਦੀ ਡਿਫੌਲਟ ਸਥਿਤੀ 'ਤੇ ਡਰਾਅ ਕਰ ਚੁੱਕਾ ਹੁੰਦਾ ਹੈ, ਸ਼ਾਇਦ top: 0, left: 0 'ਤੇ। ਉਸ ਪੇਂਟ ਤੋਂ ਬਾਅਦ ਹੀ ਤੁਹਾਡਾ effect state ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ। React ਸਹੀ ਕੋਆਰਡੀਨੇਟਸ ਨੂੰ commit ਕਰਦਾ ਹੈ, ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੁਬਾਰਾ ਪੇਂਟ ਕਰਦਾ ਹੈ। ਉਪਭੋਗਤਾ ਦੋ ਫਰੇਮ ਦੇਖਦਾ ਹੈ: ਪਹਿਲਾਂ ਗਲਤ ਸਥਿਤੀ, ਫਿਰ ਸਹੀ ਸਥਿਤੀ। ਉਹ ਵਿਜ਼ੂਅਲ ਝਟਕਾ ਹੀ ਫਲਿੱਕਰ ਹੈ ਜਿਸ ਤੋਂ ਹਰ ਕੋਈ ਬਚਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ।
ਡਾਟਾ ਫੈਚਿੰਗ, API ਕਾਲਾਂ, ਐਨਾਲਿਟਿਕਸ ਟ੍ਰੈਕਿੰਗ, ਜਾਂ ਇਵੈਂਟ ਲਿਸਨਰ ਸੈੱਟ ਅੱਪ ਕਰਨ ਲਈ, ਇਹ ਦੇਰੀ ਮਾਇਨੇ ਨਹੀਂ ਰੱਖਦੀ। ਉਪਭੋਗਤਾ ਨੂੰ ਇਸ ਨਾਲ ਕੋਈ ਫਰਕ ਨਹੀਂ ਪੈਂਦਾ ਕਿ ਐਨਾਲਿਟਿਕਸ ਬੀਕਨ ਪੇਂਟ ਤੋਂ ਕੁਝ ਮਿਲੀਸਕਿੰਟ ਬਾਅਦ ਚੱਲਦਾ ਹੈ। ਅਸਲ ਵਿੱਚ, ਗੈਰ-ਵਿਜ਼ੂਅਲ ਕੰਮਾਂ ਨੂੰ ਪੇਂਟ ਤੋਂ ਬਾਅਦ ਤੱਕ ਰੋਕ ਕੇ ਰੱਖਣਾ ਸ਼ੁਰੂਆਤੀ ਰੈਂਡਰ ਨੂੰ ਰਿਸਪੌਂਸਿਵ ਰੱਖਦਾ ਹੈ। ਪਰ ਲੇਆਉਟ 'ਤੇ ਨਿਰਭਰ ਸੁਧਾਰਾਂ ਲਈ, useEffect ਬਹੁਤ ਦੇਰ ਨਾਲ ਆਉਂਦਾ ਹੈ।
useLayoutEffect ਪੇਂਟ ਨੂੰ ਕਿਵੇਂ ਰੋਕਦਾ ਹੈ
useLayoutEffect ਸਿੰਕ੍ਰੋਨਸਲੀ (synchronously) ਚੱਲਦਾ ਹੈ, React ਦੁਆਰਾ DOM ਵਿੱਚ ਤਬਦੀਲੀ ਕਰਨ ਤੋਂ ਤੁਰੰਤ ਬਾਅਦ ਪਰ ਬ੍ਰਾਊਜ਼ਰ ਦੁਆਰਾ ਲੇਆਉਟ ਦੀ ਗਣਨਾ ਕਰਨ ਜਾਂ ਪਿਕਸਲ ਪੇਂਟ ਕਰਨ ਦੇ ਮੌਕੇ ਤੋਂ ਪਹਿਲਾਂ। ਇਹ ਪੇਂਟ ਪਾਈਪਲਾਈਨ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਰੋਕ ਦਿੰਦਾ ਹੈ।
ਜੇਕਰ ਤੁਸੀਂ useLayoutEffect ਦੇ ਅੰਦਰ ਉਹੀ ਡ੍ਰੌਪਡਾਊਨ ਮਾਪ ਕਰਦੇ ਹੋ, ਤਾਂ ਕ੍ਰਮ ਬਦਲ ਜਾਂਦਾ ਹੈ। React ਸ਼ੁਰੂਆਤੀ DOM ਅਪਡੇਟ ਨੂੰ commit ਕਰਦਾ ਹੈ, ਤੁਹਾਡਾ ਲੇਆਉਟ effect ਚਲਾਉਂਦਾ ਹੈ, ਅਤੇ ਤੁਹਾਡਾ state ਅਪਡੇਟ ਇੱਕ ਸਿੰਕ੍ਰੋਨਸ ਰੀ-ਰੈਂਡਰ ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦਾ ਹੈ। React ਸਹੀ ਕੋਆਰਡੀਨੇਟਸ ਨੂੰ commit ਕਰਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਹੀ ਬ੍ਰਾਊਜ਼ਰ ਪੇਂਟ ਕਰਦਾ ਹੈ। ਉਪਭੋਗਤਾ ਇੱਕ ਫਰੇਮ ਦੇਖਦਾ ਹੈ, ਜੋ ਪਹਿਲਾਂ ਹੀ ਸਹੀ ਹੁੰਦਾ ਹੈ।
ਉਹ ਬਲਾਕਿੰਗ ਵਿਵਹਾਰ ਹੀ ਫੀਚਰ ਵੀ ਹੈ ਅਤੇ ਜੋਖਮ ਵੀ। ਕਿਉਂਕਿ useLayoutEffect ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਪੇਂਟ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ ਜਦੋਂ ਤੱਕ ਇਹ ਖਤਮ ਨਹੀਂ ਹੋ ਜਾਂਦਾ, ਇਸਦੇ ਅੰਦਰ ਕੋਈ ਵੀ ਭਾਰੀ ਗਣਨਾ UI ਨੂੰ ਫ੍ਰੀਜ਼ ਕਰ ਦਿੰਦੀ ਹੈ। ਕੁਝ ਦਰਜਨ ਮਿਲੀਸਕਿੰਟਾਂ ਦਾ ਰੋਕਿਆ ਹੋਇਆ ਪੇਂਟ ਵੀ ਉਪਭੋਗਤਾ ਨੂੰ 'ਜੈਂਕ' (jank) ਵਾਂਗ ਮਹਿਸੂਸ ਹੁੰਦਾ ਹੈ। ਇਸੇ ਲਈ React ਦੇ ਦਸਤਾਵੇਜ਼ ਤੁਹਾਨੂੰ ਸਪੱਸ਼ਟ ਤੌਰ 'ਤੇ ਕਹਿੰਦੇ ਹਨ ਕਿ useEffect ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ ਅਤੇ useLayoutEffect ਵੱਲ ਉਦੋਂ ਹੀ ਵਧੋ ਜਦੋਂ ਤੁਸੀਂ ਅਸਲ ਵਿੱਚ ਅਜਿਹਾ ਫਲਿੱਕਰ ਦੇਖਦੇ ਹੋ ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਸਹਿ ਨਹੀਂ ਸਕਦੇ।
ਹਰੇਕ ਹੁੱਕ ਦੀ ਵਰਤੋਂ ਕਦੋਂ ਕਰਨੀ ਹੈ
ਤੁਹਾਡਾ ਜ਼ਿਆਦਾਤਰ ਲੌਜਿਕ useEffect ਵਿੱਚ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ। ਇਸਦੀ ਵਰਤੋਂ ਕਰੋ:
- API ਤੋਂ ਡਾਟਾ ਫੈਚ ਕਰਨ ਲਈ
- ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਜਾਂ ਇਵੈਂਟ ਲਿਸਨਰ ਸੈੱਟ ਅੱਪ ਕਰਨ ਲਈ
- ਐਨਾਲਿਟਿਕਸ ਇਵੈਂਟਸ ਭੇਜਣ ਲਈ
- ਕੋਈ ਵੀ ਅਜਿਹਾ ਸਾਈਡ ਇਫੈਕਟ ਜੋ ਤੁਰੰਤ ਲੇਆਉਟ ਨੂੰ ਨਹੀਂ ਪੜ੍ਹਦਾ ਜਾਂ ਬਦ
ਜੇਕਰ ਤੁਸੀਂ Next.js, Remix, ਜਾਂ ਕੋਈ ਵੀ ਅਜਿਹਾ framework ਵਰਤਦੇ ਹੋ ਜੋ server 'ਤੇ React ਨੂੰ render ਕਰਦਾ ਹੈ, ਤਾਂ ਤੁਹਾਨੂੰ useLayoutEffect ਨਾਲ ਇੱਕ warning ਮਿਲੇਗੀ। ਕਿਉਂਕਿ server ਕੋਲ ਕੋਈ DOM ਨਹੀਂ ਹੁੰਦਾ, ਇਸ ਲਈ hook ਕੋਲ ਮਾਪਣ (measure) ਲਈ ਕੁਝ ਨਹੀਂ ਹੁੰਦਾ। React ਤੁਹਾਨੂੰ ਚੇਤਾਵਨੀ ਦਿੰਦਾ ਹੈ ਕਿ ਉਸਨੇ ਇੱਕ browser environment ਦੀ ਉਮੀਦ ਕੀਤੀ ਸੀ ਪਰ ਉਹ ਮਿਲਿਆ ਨਹੀਂ। Hydration ਦੌਰਾਨ, ਇਹ mismatch ਬਾਰੀਕ bugs ਦਾ ਕਾਰਨ ਵੀ ਬਣ ਸਕਦਾ ਹੈ ਕਿਉਂਕਿ server-rendered markup ਅਤੇ client ਦਾ ਪਹਿਲਾ intended render ਵੱਖਰਾ ਹੋ ਸਕਦਾ ਹੈ।
ਇਸਦਾ ਮਿਆਰੀ ਹੱਲ ਇੱਕ isomorphic hook ਹੈ ਜੋ environment ਦੇ ਅਧਾਰ 'ਤੇ ਸਹੀ effect ਦੀ ਚੋਣ ਕਰਦਾ ਹੈ:
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
ਇਸ wrapper ਨੂੰ ਕਿਸੇ ਵੀ ਅਜਿਹੇ component ਵਿੱਚ ਵਰਤੋ ਜਿਸ ਨੂੰ DOM nodes ਨੂੰ ਮਾਪਣ ਦੀ ਲੋੜ ਹੈ ਪਰ ਉਹ server rendering ਦੌਰਾਨ ਚੱਲ ਸਕਦਾ ਹੈ। ਇਹ warning ਨੂੰ ਰੋਕਦਾ ਹੈ ਅਤੇ ਤੁਹਾਡੇ server output ਨੂੰ consistent ਰੱਖਦਾ ਹੈ।
Performance ਅਤੇ Best Practices
ਕਿਉਂਕਿ useLayoutEffect painting ਨੂੰ ਰੋਕਦਾ ਹੈ, ਇਸ ਲਈ hook ਦੀ body ਨੂੰ ਜਿੰਨਾ ਹੋ ਸਕੇ ਹਲਕਾ (light) ਰੱਖੋ। Layout value ਨੂੰ ਪੜ੍ਹੋ, correction ਦੀ ਗਣਨਾ ਕਰੋ, ਅਤੇ ਇਸਨੂੰ ਵਾਪਸ ਲਿਖੋ। ਇਸਦੇ ਅੰਦਰ data fetch ਨਾ ਕਰੋ, ਵੱਡੀਆਂ objects ਨੂੰ parse ਨਾ ਕਰੋ, ਜਾਂ ਮਹਿੰਗੇ (expensive) algorithms ਨਾ ਚਲਾਓ। ਇੱਥੇ ਭਾਰੀ code main thread ਨੂੰ ਰੋਕ ਦੇਵੇਗਾ ਅਤੇ ਤੁਹਾਡੇ interface ਨੂੰ frozen ਮਹਿਸੂਸ ਕਰਵਾਏਗਾ।
ਜਦੋਂ ਤੁਸੀਂ elements ਨੂੰ ਮਾਪਦੇ ਹੋ, ਤਾਂ document.getElementById ਦੀ ਬਜਾਏ React refs ਦੀ ਵਰਤੋਂ ਕਰੋ। Refs ਤੁਹਾਡੇ component instance ਨਾਲ ਜੁੜੇ ਹੁੰਦੇ ਹਨ, query tricks ਤੋਂ ਬਿਨਾਂ re-renders ਵਿੱਚ ਬਣੇ ਰਹਿੰਦੇ ਹਨ, ਅਤੇ portals ਜਾਂ conditional rendering ਨਾਲ ਭਰੋਸੇਮੰਦ ਤਰੀਕੇ ਨਾਲ ਕੰਮ ਕਰਦੇ ਹਨ। Global ID lookups component encapsulation ਨੂੰ ਤੋੜਦੇ ਹਨ ਅਤੇ ਬਿਲਕੁਲ ਉਸੇ ਸਮੇਂ null ਵਾਪਸ ਕਰ ਸਕਦੇ ਹਨ ਜਦੋਂ ਤੁਹਾਨੂੰ ਉਹਨਾਂ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।
ਲਗਭਗ ਹਰ side effect ਲਈ useEffect ਸਹੀ default ਹੈ। ਇਹ browser ਨੂੰ ਬਿਨਾਂ ਕਿਸੇ ਰੁਕਾਵਟ ਦੇ paint ਕਰਨ ਦਿੰਦਾ ਹੈ ਅਤੇ data, events, ਅਤੇ external synchronization ਨੂੰ ਸਾਫ਼ ਤਰੀਕੇ ਨਾਲ ਸੰਭਾਲਦਾ ਹੈ। useLayoutEffect ਇੱਕ ਖਾਸ ਸਮੱਸਿਆ ਲਈ ਇੱਕ ਵਿਸ਼ੇਸ਼ tool ਹੈ: paint ਤੋਂ ਪਹਿਲਾਂ layout ਨੂੰ ਪੜ੍ਹਨਾ ਅਤੇ ਵਾਪਸ ਲਿਖਣਾ। ਇਹਨਾਂ ਵਿਚਕਾਰ timing ਦੇ ਅੰਤਰ ਵਿੱਚ ਮਾਹਰ ਬਣੋ, ਅਤੇ ਤੁਸੀਂ flickers ਦਾ ਪਿੱਛਾ ਕਰਨਾ ਬੰਦ ਕਰਕੇ ਉਹਨਾਂ ਨੂੰ ਰੋਕਣਾ ਸ਼ੁਰੂ ਕਰ ਦਿਓਗੇ।
ਅਸਲ ਸਿੱਖ (The real takeaway): ਹਰ ਚੀਜ਼ ਲਈ useEffect ਨਾਲ ਸ਼ੁਰੂਆਤ ਕਰੋ। ਜਿਸ ਪਲ ਤੁਹਾਨੂੰ ਕੋਈ tooltip ਜਾਂ modal ਆਪਣੇ ਆਪ ਨੂੰ ਠੀਕ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਗਲਤ ਜਗ੍ਹਾ 'ਤੇ blink ਹੁੰਦਾ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ, ਉਹ ਤੁਹਾਡਾ ਸੰਕੇਤ ਹੈ। useLayoutEffect 'ਤੇ ਬਦਲੋ, DOM ਨੂੰ ਮਾਪੋ, ਆਪਣੇ layout ਨੂੰ ਐਡਜਸਟ ਕਰੋ, ਅਤੇ browser ਨੂੰ ਇੱਕ ਵਾਰ—ਸਹੀ ਤਰੀਕੇ ਨਾਲ paint ਕਰਨ ਦਿਓ।
