web-dev-qa-db-fra.com

Comment détecter l'appareil sur React SSR App avec Next.js?

sur une application Web, je souhaite afficher deux menus différents, un pour le mobile, un pour le navigateur de bureau. J'utilise l'application Next.js avec un rendu côté serveur et la bibliothèque react-device-detect .

Voici le lien CodeSandox .

import Link from "next/link";
import { BrowserView, MobileView } from "react-device-detect";

export default () => (
  <div>
    Hello World.{" "}
    <Link href="/about">
      <a>About</a>
    </Link>
    <BrowserView>
      <h1> This is rendered only in browser </h1>
    </BrowserView>
    <MobileView>
      <h1> This is rendered only on mobile </h1>
    </MobileView>
  </div>
);

Si vous ouvrez ceci dans un navigateur et passez à la vue mobile et regardez la console, vous obtenez cette erreur:

Avertissement: le contenu du texte ne correspond pas. Serveur: "Ceci est rendu uniquement dans le navigateur" Client: "Ceci est rendu uniquement sur mobile"

Cela se produit parce que le rendu par le serveur détecte un navigateur et sur le client, il s'agit d'un appareil mobile. La seule solution de contournement que j'ai trouvée est de générer les deux et d'utiliser le CSS comme ceci:

.activeOnMobile {
  @media screen and (min-width: 800px) {
    display: none;
  }
}

.activeOnDesktop {
  @media screen and (max-width: 800px) {
    display: none;
  }
}

Au lieu de la bibliothèque mais je n'aime pas vraiment cette méthode. Quelqu'un connaît-il la bonne pratique pour gérer le type de périphérique sur une application SSR directement dans le code de réaction?

5
Benjamin Sx

Je pense que vous devriez le faire en utilisant getInitialProps dans votre page, car il fonctionne à la fois sur le serveur et sur le client, et en obtenant le type d'appareil en détectant d'abord si vous recevez juste la demande de la page Web (vous êtes donc toujours sur le serveur), ou si vous effectuez un nouveau rendu (vous êtes donc sur le client).

// index.js

IndexPage.getInitialProps = ({ req }) => {
  let userAgent;
  if (req) { // if you are on the server and you get a 'req' property from your context
    userAgent = req.headers['user-agent'] // get the user-agent from the headers
  } else {
    userAgent = navigator.userAgent // if you are on the client you can access the navigator from the window object
  }
}

Vous pouvez maintenant utiliser une expression régulière pour voir si l'appareil est un mobile ou un ordinateur de bureau.

// still in getInitialProps

let isMobile = Boolean(userAgent.match(
  /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
))

return { isMobile }

Vous pouvez maintenant accéder à la prop isMobile qui renverra soit vrai ou faux

const IndexPage = ({ isMobile }) => {
  return ( 
    <div>
     {isMobile ? (<h1>I am on mobile!</h1>) : (<h1>I am on desktop! </h1>)} 
    </div>
  )
}

J'ai eu cette réponse de cet article ici J'espère que cela vous a été utile

3
Dylanbob211