ਆਧੁਨਿਕ ਵੈੱਬਸਾਈਟਾਂ ਵੱਧ ਤੋਂ ਵੱਧ ਸ਼ਾਨਦਾਰ ਵਿਜ਼ੂਅਲਸ ਨਾਲ ਧਿਆਨ ਖਿੱਚਣ ਲਈ ਮੁਕਾਬਲਾ ਕਰਦੀਆਂ ਹਨ। Parallax heroes ਵਿਊਪੋਰਟ (viewport) ਵਿੱਚ ਡੂੰਘੇ ਤੱਕ ਫੈਲੇ ਹੁੰਦੇ ਹਨ। Carousels ਲਗਾਤਾਰ ਸਕ੍ਰੋਲ ਹੁੰਦੇ ਰਹਿੰਦੇ ਹਨ। Signup ਫਾਰਮਾਂ ਦੇ ਪਿੱਛੇ ਬੈਕਗ੍ਰਾਊਂਡ ਵੀਡੀਓਜ਼ ਆਪਣੇ ਆਪ ਚੱਲਣ ਲੱਗ ਜਾਂਦੀਆਂ ਹਨ। ਡਿਜ਼ਾਈਨ ਪੋਰਟਫੋਲੀਓ ਵਿੱਚ ਇਹ ਪੈਟਰਨ ਬਹੁਤ ਹੀ ਸ਼ਾਨਦਾਰ ਅਤੇ ਦਿਲਚਸਪ ਲੱਗਦੇ ਹਨ। ਪਰ ਤੁਹਾਡੇ ਦਰਸ਼ਕਾਂ ਦੇ ਇੱਕ ਹਿੱਸੇ ਲਈ, ਇਹ ਇੱਕ ਸਰੀਰਕ ਪ੍ਰਤੀਕਿਰਿਆ (physical trigger) ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ।

ਵੈਸਟੀਬੂਲਰ ਡਿਸਆਰਡਰ (vestibular disorders) ਨਾਲ ਜੀ ਰਹੇ ਲੋਕਾਂ ਨੂੰ ਲਗਾਤਾਰ ਚਲਦੇ ਰਹਿਣ ਵਾਲੇ ਵੱਡੇ ਖੇਤਰਾਂ ਦੇ ਸਾਹਮਣੇ ਆਉਣ 'ਤੇ ਉਲਟੀ, ਚੱਕਰ ਆਉਣ ਜਾਂ ਮਾਈਗ੍ਰੇਨ ਵਰਗੀਆਂ ਸਮੱਸਿਆਵਾਂ ਦਾ ਸਾਹਮਣਾ ਕਰਨਾ ਪੈਂਦਾ ਹੈ। ਉਨ੍ਹਾਂ ਦੀ ਸੁਰੱਖਿਆ ਲਈ, ਹੁਣ ਹਰ ਪ੍ਰਮੁੱਖ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਵਿੱਚ "Reduce Motion" ਐਕਸੈਸਬਿਲਟੀ ਸੈਟਿੰਗ ਸ਼ਾਮਲ ਹੈ। ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਰ prefers-reduced-motion ਮੀਡੀਆ ਕੁਐਰੀ (media query) ਰਾਹੀਂ ਉਸ ਪਸੰਦ ਨੂੰ ਪ੍ਰਗਟ ਕਰਦੇ ਹਨ। React ਡਿਵੈਲਪਰ ਜੋ ਇਸ ਦਾ ਸਾਫ਼-ਸੁਥਰੇ ਤਰੀਕੇ ਨਾਲ ਸਤਿਕਾਰ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹਨ, ਉਹ @reactuses/core ਤੋਂ useReducedMotion ਹੁੱਕ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹਨ। ਇਹ OS ਦੀ ਪਸੰਦ ਨੂੰ ਇੱਕ ਬੂਲੀਅਨ (boolean) ਵਿੱਚ ਪੜ੍ਹਦਾ ਹੈ, ਜੇਕਰ ਯੂਜ਼ਰ ਆਪਣੀ ਪਸੰਦ ਬਦਲਦਾ ਹੈ ਤਾਂ ਤੁਰੰਤ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, ਅਤੇ ਸਰਵਰ-ਸਾਈਡ ਰੈਂਡਰਿੰਗ (server-side rendering) ਨੂੰ ਬਿਨਾਂ ਕਿਸੇ ਗਲਤੀ ਦੇ ਸੰਭਾਲਦਾ ਹੈ।

ਖੁਦ ਬਣਾਏ ਗਏ ਹੱਲ ਕਿਉਂ ਅਸਫਲ ਹੁੰਦੇ ਹਨ

ਤੁਸੀਂ window.matchMedia('(prefers-reduced-motion: reduce)') ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਖੁਦ ਇਸ ਪਸੰਦ ਬਾਰੇ ਪੁੱਛ ਸਕਦੇ ਹੋ। ਬਹੁਤ ਸਾਰੇ ਡਿਵੈਲਪਰ ਅਜਿਹਾ ਕਰਦੇ ਹਨ, ਅਤੇ ਕਈ ਵਾਰ ਇਸ ਨਾਲ ਮਾਮੂਲੀ ਬੱਗ (bugs) ਪੈਦਾ ਹੋ ਜਾਂਦੇ ਹਨ।

ਪਹਿਲਾ, ਤੁਸੀਂ ਆਸਾਨੀ ਨਾਲ 'ਚੇਂਜ ਲਿਸਨਰ' (change listener) ਨੂੰ ਭੁੱਲ ਸਕਦੇ ਹੋ। ਸ਼ੁਰੂਆਤੀ ਕੁਐਰੀ ਕੰਪੋਨੈਂਟ ਮਾਊਂਟ (mount) ਹੋਣ ਵੇਲੇ ਇੱਕ ਵਾਰ ਚੱਲਦੀ ਹੈ। ਜੇਕਰ ਕੋਈ ਯੂਜ਼ਰ ਤੁਹਾਡੀ ਐਪ ਖੋਲ੍ਹਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ ਵਿੱਚ 'Reduce Motion' ਨੂੰ ਬਦਲ ਦਿੰਦਾ ਹੈ ਕਿਉਂਕਿ ਇੱਕ ਕੈਰੋਸਲ (carousel) ਉਨ੍ਹਾਂ ਨੂੰ ਬੀਮਾਰ ਕਰ ਰਿਹਾ ਹੈ, ਤਾਂ ਤੁਹਾਡਾ ਕੰਪੋਨੈਂਟ ਉਸ ਅਪਡੇਟ ਬਾਰੇ ਕਦੇ ਨਹੀਂ ਜਾਣ ਸਕੇਗਾ। ਮੀਡੀਆ ਕੁਐਰੀ ਆਬਜੈਕਟ addEventListener ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ, ਪਰ ਇਸ ਨੂੰ ਸਹੀ ਤਰੀਕੇ ਨਾਲ ਜੋੜਨਾ, ਅਨਮਾਊਂਟ (unmount) ਹੋਣ 'ਤੇ ਇਸ ਨੂੰ ਹਟਾਉਣਾ, ਅਤੇ ਪੁਰਾਣੇ addListener ਸਿੰਟੈਕਸ ਨੂੰ ਪੋਲੀਫਿਲ (polyfill) ਕਰਨਾ ਅਜਿਹਾ ਕੰਮ ਹੈ ਜਿਸ ਵਿੱਚ ਕਾਪੀ-ਪੇਸਟ ਦੀਆਂ ਗਲਤੀਆਂ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ ਬਹੁਤ ਜ਼ਿਆਦਾ ਹੁੰਦੀ ਹੈ।

ਦੂਜਾ, SSR ਦੌਰਾਨ window ਮੌਜੂਦ ਨਹੀਂ ਹੁੰਦਾ। ਜੇਕਰ ਤੁਹਾਡੀ ਐਪ ਸਰਵਰ 'ਤੇ ਰੈਂਡਰ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਇੱਕ ਸਧਾਰਨ matchMedia ਕਾਲ ਰੈਫਰੈਂਸ ਐਰਰ (reference error) ਦਿੰਦੀ ਹੈ ਅਤੇ ਰੈਂਡਰਿੰਗ ਨੂੰ ਰੋਕ ਦਿੰਦੀ ਹੈ। ਅੰਤ ਵਿੱਚ, ਤੁਹਾਨੂੰ ਚੈੱਕ ਨੂੰ typeof window !== 'undefined' ਗਾਰਡਾਂ ਵਿੱਚ ਲਪੇਟਣਾ ਪੈਂਦਾ ਹੈ, ਡਿਫੌਲਟ ਅੰਦਾਜ਼ਾ ਲਗਾਉਣਾ ਪੈਂਦਾ ਹੈ, ਅਤੇ ਉਮੀਦ ਕਰਨੀ ਪੈਂਦੀ ਹੈ ਕਿ ਕਲਾਇੰਟ ਹਾਈਡ੍ਰੇਸ਼ਨ (client hydration) ਮੇਲ ਖਾਂਦਾ ਹੈ।

ਤੀਜਾ, ਹਰ ਐਨੀਮੇਟਡ ਕੰਪੋਨੈਂਟ ਵਿੱਚ ਉਸੇ ਲੌਜਿਕ ਨੂੰ ਦੁਹਰਾਉਣਾ ਮੇਨਟੇਨੈਂਸ ਦੇ ਬੋਝ (maintenance debt) ਵਿੱਚ ਬਦਲ ਜਾਂਦਾ ਹੈ। ਇੱਕ ਸਾਥੀ ਲਿਸਨਰ ਨੂੰ ਇੱਕ ਤਰੀਕੇ ਨਾਲ ਲਿਖਦਾ ਹੈ, ਦੂਜਾ ਇਸ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਛੱਡ ਦਿੰਦਾ ਹੈ, ਅਤੇ ਤੀਜਾ ਇੱਕ ਅਜਿਹਾ ਡਿਫੌਲਟ ਹਾਰਡ-ਕੋਡ ਕਰ ਦਿੰਦਾ ਹੈ ਜੋ ਮੋਸ਼ਨ (motion) ਨੂੰ ਪਸੰਦ ਕਰਦਾ ਹੈ। ਇੱਕ ਹੁੱਕ ਇਸ ਸਾਰੀ ਉਲਝਣ ਨੂੰ ਕੇਂਦਰਿਤ ਕਰ ਦਿੰਦਾ ਹੈ।

useReducedMotion ਇਹਨਾਂ ਤਿੰਨਾਂ ਸਮੱਸਿਆਵਾਂ ਦਾ ਹੱਲ ਕਰਦਾ ਹੈ। ਇਹ ਇੱਕ ਸਧਾਰਨ ਬੂਲੀਅਨ ਰਿਟਰਨ ਕਰਦਾ ਹੈ। ਇਹ ਸਰਵਰ 'ਤੇ ਸੁਰੱਖਿਅਤ ਰੂਪ ਵਿੱਚ 'no-op' ਰਹਿੰਦਾ ਹੈ। ਇਹ ਲਿਸਨਰ ਨੂੰ ਆਪਣੇ ਆਪ ਜੋੜਦਾ ਹੈ ਅਤੇ ਸਾਫ਼ ਕਰਦਾ ਹੈ।

ਇਸ ਨੂੰ ਵਰਤਣ ਦੇ ਤਿੰਨ ਤਰੀਕੇ

ਇੱਕ ਵਾਰ ਜਦੋਂ ਤੁਹਾਡੇ ਕੋਲ ਬੂਲੀਅਨ ਹੋ ਜਾਵੇ, ਤਾਂ ਤੁਹਾਨੂੰ ਇਸ 'ਤੇ ਕਾਰਵਾਈ ਕਰਨ ਲਈ ਇੱਕ ਰਣਨੀਤੀ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਇੱਥੇ ਤਿੰਨ ਪੈਟਰਨ ਹਨ ਜੋ ਇੱਕ ਸਿੰਗਲ ਕੰਪੋਨੈਂਟ ਤੋਂ ਲੈ ਕੇ ਪੂਰੀ ਐਪਲੀਕੇਸ਼ਨ ਤੱਕ ਵਰਤੇ ਜਾ ਸਕਦੇ ਹਨ।

1. ਫਾਲਤੂ ਕੰਮ ਤੋਂ ਬਚਣ ਲਈ CSS ਕਲਾਸਾਂ ਨੂੰ ਰੋਕੋ (Gate)

ਸਭ ਤੋਂ ਸਿੱਧਾ ਤਰੀਕਾ ਭਾਰੀ JavaScript ਐਨੀਮੇਸ਼ਨ ਲੂਪਸ (loops) ਨੂੰ ਸ਼ੁਰੂ ਹੋਣ ਤੋਂ ਰੋਕਣਾ ਹੈ। ਕਲਪਨਾ ਕਰੋ ਕਿ ਤੁਹਾਡੇ ਕੋਲ ਇੱਕ parallax ਇਮੇਜ ਕੰਪੋਨੈਂਟ ਹੈ ਜੋ ਆਮ ਤੌਰ 'ਤੇ ਸਕ੍ਰੋਲ ਇਵੈਂਟਸ ਨੂੰ ਸੁਣਦਾ ਹੈ ਅਤੇ requestAnimationFrame ਲੂਪ ਦੇ ਅੰਦਰ ਲੇਅਰਾਂ ਨੂੰ ਟ੍ਰਾਂਸਲੇਟ ਕਰਦਾ ਹੈ। ਉਸ ਲੌਜਿਕ ਨੂੰ ਚਲਾਉਣ ਅਤੇ ਫਿਰ ਵਿਜ਼ੂਅਲ ਨਤੀਜੇ ਨੂੰ ਰੋਕਣ ਦੀ ਬਜਾਏ, ਪਹਿਲਾਂ useReducedMotion ਦੀ ਜਾਂਚ ਕਰੋ।

ਜੇਕਰ ਹੁੱਕ true ਰਿਟਰਨ ਕਰਦਾ ਹੈ, ਤਾਂ ਕੰਪੋਨੈਂਟ ਨੂੰ ਇੱਕ ਸਟੈਟਿਕ ਵੇਰੀਐਂਟ ਕਲਾਸ (static variant class) ਨਾਲ ਰੈਂਡਰ ਕਰੋ ਅਤੇ ਉਸ useEffect ਨੂੰ ਛੱਡ ਦਿਓ ਜੋ ਸਕ੍ਰੋਲ ਲਿਸਨਰਾਂ ਨੂੰ ਬੰਨ੍ਹਦਾ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਘੱਟ ਕੰਮ ਕਰਦਾ ਹੈ। ਮੋਸ਼ਨ ਸੰਵੇਦਨਸ਼ੀਲਤਾ (motion sensitivity) ਵਾਲੇ ਯੂਜ਼ਰਾਂ ਨੂੰ ਇੱਕ ਫਿਕਸਡ ਇਮੇਜ ਦਿਖਾਈ ਦਿੰਦੀ ਹੈ। ਬਾਕੀ ਸਭ ਨੂੰ ਚਲਦੀਆਂ ਲੇਅਰਾਂ ਮਿਲਦੀਆਂ ਹਨ। ਕਿਉਂਕਿ ਐਨੀਮੇਸ਼ਨ ਕੋਡ ਕਦੇ ਸ਼ੁਰੂ ਹੀ ਨਹੀਂ ਹੁੰਦਾ, ਇਸ ਲਈ ਤੁਸੀਂ CPU ਅਤੇ ਬੈਟਰੀ ਦੀ ਵੀ ਬਚਤ ਕਰਦੇ ਹੋ।

2. ਇਸ ਨੂੰ ਸਿੱਧਾ ਐਨੀਮੇਸ਼ਨ ਲਾਇਬ੍ਰੇਰੀਆਂ ਵਿੱਚ ਵਰਤੋ

ਜੇਕਰ ਤੁਸੀਂ Framer Motion ਵਰਗੀ ਲਾਇਬ੍ਰੇਰੀ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਹੋ, ਤਾਂ ਇਹ ਹੁੱਕ ਤੁਹਾਡੀਆਂ prop ਡੈਫੀਨੇਸ਼ਨਾਂ ਵਿੱਚ ਸਿੱਧਾ ਜੁੜ ਜਾਂਦਾ ਹੈ। Motion ਕੰਪੋਨੈਂਟ ਵੇਰੀਐਂਟਸ, ਟ੍ਰਾਂਜ਼ੀਸ਼ਨਾਂ ਅਤੇ ਜੈਸਚਰਾਂ (gestures) ਲਈ ਕੌਂਫਿਗਰੇਸ਼ਨ ਆਬਜੈਕਟਸ ਸਵੀਕਾਰ ਕਰਦੇ ਹਨ। ਤੁਸੀਂ ਟ੍ਰਾਂਜ਼ੀਸ਼ਨਾਂ 'ਤੇ ਸ਼ਰਤ ਦੇ ਅਧਾਰ 'ਤੇ duration: 0 ਸੈੱਟ ਕਰਨ ਲਈ useReducedMotion ਤੋਂ ਬੂਲੀਅਨ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ, ਜਾਂ