Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 11, 2020 04:00 am GMT

How to Create a Custom useDeviceDetect() React Hook

Hooks are great because they give you the tools to solve problems in your code. For example, an existing library may not have a feature you need.

I came across one such problem today that required the making a custom hook.

Im in the process of building a new landing page for a course of mine, and I experienced a very strange error on mobile devices. On desktop computers, the styles looked great.

But when I looked at on mobile, everything was out of place and broken.

React App Error

I tracked the problem down to one library called react-device-detect which I was using to detect whether users had a mobile device or not. If so, I would remove the header.

// templates/course.jsimport React from "react";import { isMobile } from "react-device-detect";function Course() {  return (    <>      <SEO />      {!isMobile && <StickyHeader {...courseData} />}      {/* more components... */}    </>  );}

The problem was that this library doesnt have support for server-side rendering, which is what Gatsby uses by default. So I needed to create my own solution to check when a users on a mobile device. And for that, I decided to make a custom hook with the name useDeviceDetect.

Creating the Hook

I created a separate file for this hook in my utils folder with the same name, useDeviceDetect.js. Since hooks are just shareable JavaScript functionswhich leverage react hooks, I created a function called useDeviceDetectand imported React.

// utils/useDeviceDetect.jsimport React from "react";export default function useDeviceDetect() {}

Getting the User Agent from Window

The way that we can make sure whether we can get information about the users device is through the userAgent property (located on the navigator property of window).

And since interacting with the window API, as an API / external resource, would be classed as a side effect we need to get access to the user agent within the useEffect hook.

// utils/useDeviceDetect.jsimport React from "react";export default function useDeviceDetect() {  React.useEffect(() => {    console.log(`user's device is: ${window.navigator.userAgent}`);    // can also be written as 'navigator.userAgent'  }, []);}

Once the component mounts we can use typeof navigator to determine if we are on the client or server. If were on the server, we wont have access to the window. typeof navigator will be equal to the string undefined since its not there. Otherwise, if were on the client, well be able to get our user agent property.

We can express all this using a ternary to get the userAgent data:

// utils/useDeviceDetect.jsimport React from "react";export default function useDeviceDetect() {  React.useEffect(() => {    const userAgent =      typeof navigator === "undefined" ? "" : navigator.userAgent;  }, []);}

Checking if userAgent is a mobile device

userAgent is a string value which will be set to any one of the following device names if they are using a mobile device:

Android, BlackBerry, iPhone, iPad, iPod, Opera Mini, IEMobile, or WPDesktop.

All we have to do is take the string, we get and use the .match() methodwith a regex to see whether its any one of these strings. Well store it in a local variable called mobile.

Well store the result in state with the useState hook, which well give an initial value of false. For it, well create a corresponding state variable isMobile, and the setter will be setMobile.

// utils/useDeviceDetect.jsimport React from "react";export default function useDeviceDetect() {  const [isMobile, setMobile] = React.useState(false);  React.useEffect(() => {    const userAgent =      typeof window.navigator === "undefined" ? "" : navigator.userAgent;    const mobile = Boolean(      userAgent.match(        /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i      )    );    setMobile(mobile);  }, []);}

So once we get the mobile value we will set it in state and then finally we will return an object from the hook so we can add more values in the future if we want to choose to add more functionality to this hook.

Within the object, well add isMobile as a property and value:

// utils/useDeviceDetect.jsimport React from "react";export default function useDeviceDetect() {  const [isMobile, setMobile] = React.useState(false);  React.useEffect(() => {    const userAgent =      typeof window.navigator === "undefined" ? "" : navigator.userAgent;    const mobile = Boolean(      userAgent.match(        /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i      )    );    setMobile(mobile);  }, []);  return { isMobile };}

Back in the landing page we can execute the hook and simply get that property from the destructured object and use it where we need.

// templates/course.jsimport React from "react";import useDeviceDetect from "../utils/useDeviceDetect";function Course() {  const { isMobile } = useDeviceDetect();  return (    <>      <SEO />      {!isMobile && <StickyHeader {...courseData} />}      {/* more components... */}    </>  );}

So heres a clear cut example of how hooks can give us the tools to fix our own problems when third-party libraries fall short.

Feel free to use this hook in your own code if youre using a server-side rendered React framework like Gatsby or Next.js need to detect whether the user is on a mobile device. It wouldnt be hard to extend this feature and make another state variable to check if the user is on a desktop.

Want To Become a JS Master? Join the 2020 JS Bootcamp

Join the JS Bootcamp Course

Follow + Say Hi! Twitter Instagram reedbarger.com codeartistry.io


Original Link: https://dev.to/codeartistryio/how-to-create-a-custom-usedevicedetect-react-hook-56l1

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To