.

HD Mp4 3gp Video
Live Update Video
Play/Download
Live 3D App
Search.Pencarian Menu

Add text send email to rh3252705.adda@blogger.com or Click this (Text porn Will delete) | Tambah teks kirim email ke rh3252705.adda@blogger.com atau Klik ini (Teks porno akan dihapus)
Total pos : 19157+

[Go Make Things] A custom React hook for watching media query changes

Today's newsletter is sponsored by ConfigCat — the feature flag service that helps you release features faster and with less risk. More on them at the end of today's newsletter.

A few weeks ago, I wrote about how to watch for media query changes with JavaScript.

Today, I wanted to share a little custom React hook you can use to detect media changes and automatically trigger a new render when it happens.

Let's dig in!

An example

Let's imagine you have a component with a video animation.

function AnimatedChart ({ src }) {  	return (  		<video   			autoPlay={true}  			muted={true}  			loop={true}  			src={src}  		>  	);  }

If the user has prefers-reduced-motion enabled, you want to show a static image instead.

And, if they change their setting once the component is already in the DOM, you want to update it (either stopping the video, or adding it back in, accordingly).

Creating a custom React hook

We'll start by importing useEffect() and useState(), as we'll need both of them.

We'll also create our hook, useWatchMatchMedia(), and export it. The hook accepts the match media selector as an argument.

import { useEffect, useState } from 'react';    /**   * A hook to checks for matchMedia() settings and react to changes   * @param {string} selector The match media selector string   * @return {state}           The state object   */  export function useWatchMatchMedia (selector) {  	// Code will go here...  }

Inside our hook, we'll set an initial state of false, and assign the state and setter function to the matches and setMatches variables, respectively.

We'll return the matches state back out as an object property.

/**   * A hook to checks for matchMedia() settings and react to changes   * @param  {string} selector The match media selector string   * @return {state}           The state object   */  export function useWatchMatchMedia (selector) {    	// If true, user prefers reduced motion  	const [matches, setMatches] = useState(false);    	return { matches };    }

Setting matches based on media query

Next, we'll use useEffect() to check for the actual media query value when the component is rendered. We'll pass in the selector as a dependency.

/**   * A hook to checks for matchMedia() settings and react to changes   * @param  {string} selector The match media selector string   * @return {state}           The state object   */  export function useWatchMatchMedia (selector) {    	// If true, user prefers reduced motion  	const [matches, setMatches] = useState(false);    	// On render, sets user preference and listens for changes  	useEffect(() => {  		// ...  	}, [selector]);    	return { matches };    }

We do this in useEffect() instead of when setting our initial state because in some setups, the window object used for the matchMedia() method isn't available when the component first loads.

Inside the useEffect() callback function, we'll pass our selector into window.matchMedia(), get the returned MatchMedia object, and pass its .matches property into setMatches() to set the current state.

// On render, sets user preference and listens for changes  useEffect(() => {  	const prefersReducedMotion = window.matchMedia(selector);  	setMatches(prefersReducedMotion.matches);  }, [selector]);

Listening for query changes

We also want to update our matches state when the user updates their settings or the query value changes.

We'll create an updateMatches() method that will run whenever there's a change to the MatchMedia object, and updates the matches state. Then we'll listen for change events on the object, and pass the function in as a callback.

We'll also return a function that removes the event listener when the component is removed, so we don't have unnecessary event listeners cluttering up browser memory.

// On render, sets user preference and listens for changes  useEffect(() => {  	const prefersReducedMotion = window.matchMedia(selector);  	setMatches(prefersReducedMotion.matches);    	// Callback function for updating user preference  	function updateMatches (event) {  		setMatches(event.matches);  	}    	prefersReducedMotion.addEventListener('change', updateMatches);    	return () => {  		prefersReducedMotion.removeEventListener('change', updateMatches);  	};  }, [selector]);

Using the useWatchMatchMedia() hook in our component

Back in our <AnimatedChart /> component, we'll import the new useWatchMatchMedia() hook.

Then we'll run it, passing in (prefers-reduced-motion) as the selector. We'll assign the returned matches variable to a variable, and rename it prefersReducedMotion for clarity.

function AnimatedChart ({ src }) {    	const { prefersReducedMotion } = useWatchMatchMedia('(prefers-reduced-motion)');    	return (  		<video   			autoPlay={true}  			muted={true}  			loop={true}  			src={src}  		>  	);    }

Now, we can use the prefersReducedMotion state to conditionally render a video or image. We'll add a fallback property to our component to use.

function AnimatedChart ({   	src,   	fallback   }) {    	const { prefersReducedMotion } = useWatchMatchMedia('(prefers-reduced-motion)');    	if (prefersReducedMotion) {  		return (  			<img  				alt={fallback.alt}  				src={fallback.src}  			/>  		)  	}    	return (  		<video   			autoPlay={true}  			muted={true}  			loop={true}  			src={src}  		>  	);    }

Now, if the user has prefers-reduced-motion enabled, or toggles it on after the component is rendered, they'll get the fallback image. Otherwise, they'll get the video.

Are you looking for a service to support dynamic feature flags? ConfigCat is a cross-platform LaunchDarkly alternative that's easy to learn and quick to set up. With SDKs for 19 platforms — including JavaScript, Python, Ruby, Java, and even Rust — you can toggle features on or off without redeploying.

ConfigCat subscriptions are the same price regardless of your team size. Get 25% off any paid plan with code GO25 or just use ConfigCat's generous free tier. Definitely worth checking out.

Cheers,
Chris

Want to share this with others or read it later? View it in a browser.

Share :

Facebook Twitter Google+ Lintasme

Related Post:

0 Komentar untuk "[Go Make Things] A custom React hook for watching media query changes"

Back To Top