web-dev-qa-db-fra.com

next.js: le document n'est pas défini

J'essaie de créer un formulaire de paiement où les gens peuvent payer, mais j'obtiens toujours cette erreur. document is not defined. J'utilise next.js. S'il vous plaît voir mon code ci-dessous

import React from "react";
import {Elements, StripeProvider} from 'react-stripe-elements';
import CheckoutForm from '../../components/Payment/CheckoutForm';
import { useRouter } from 'next/router';


var stripe_load = () => {
    var aScript = document.createElement('script');
    aScript.type = 'text/javascript';
    aScript.src = " https://js.stripe.com/v3/";

    document.head.appendChild(aScript);
    aScript.onload = () => {

    };
};

function Payment({Host}) {
    const key = Host.includes('localhost') ? 'test' : 't';

    stripe_load();

    const router = useRouter();

    return (
        <div className="Payment Main">
            <StripeProvider apiKey={key}>
                <Elements>
                    <CheckoutForm planid={router.query.id}/>
                </Elements>
            </StripeProvider>
            <br/>
            <br/>
            <p>Powered by Stripe</p>
        </div>
    );
};


Payment.getInitialProps = async ctx => {
    return { Host: ctx.req.headers.Host }
};

export default Payment
4
Louisa Scheinost

Pour accéder au document dans Next.js, vous devez d'abord attendre le rendu de la page, puis l'obtenir dans une variable, comme ceci:

const [_document, set_document] = React.useState(null)

React.useEffect(() => {
    set_document(document)
}, [])
1
Maicon Gilton

Vous devez vous assurer que vous avez configuré deux choses.

  1. Le rendu DOM est terminé.
  2. Chargez ensuite la fonction.

Étape 1: créez le hook isMounted cela garantira que votre DOM est rendu.

import React, {useEffect, useState} from 'react';

function RenderCompleted() {

    const [mounted, setMounted] = useState(false);

    useEffect(() => {
        setMounted(true)

        return () => {
            setMounted(false)
        }
    });

    return mounted;
}

export default RenderCompleted;

Fonction intérieure Paiement charger le crochet:

import React, {useEffect} from "react";
import {Elements, StripeProvider} from 'react-stripe-elements';
import CheckoutForm from '../../components/Payment/CheckoutForm';
import { useRouter } from 'next/router';
import RenderCompleted from '../hooks/isMounted';

var stripe_load = () => {
    var aScript = document.createElement('script');
    aScript.type = 'text/javascript';
    aScript.src = " https://js.stripe.com/v3/";

    document.head.appendChild(aScript);
    aScript.onload = () => {

    };
};

function Payment({Host}) {
    const[key,setKey] = useEffect('');

    //will help you on re-render or Host changes

    useEffect(()=>{
        const key = Host.includes('localhost') ? 'test' : 't';
        setKey(key);
    },[Host])


    useEffect(() => {
      var aScript = document.createElement('script');
       aScript.type = 'text/javascript';
       aScript.src = " https://js.stripe.com/v3/";

       document.head.appendChild(aScript);
       aScript.onload = () => {

       };
    }, [isMounted])


    const router = useRouter();
    const isMounted = RenderCompleted();

    return (
        <div className="Payment Main">
            <StripeProvider apiKey={key}>
                <Elements>
                    <CheckoutForm planid={router.query.id}/>
                </Elements>
            </StripeProvider>
            <br/>
            <br/>
            <p>Powered by Stripe</p>
        </div>
    );
};


Payment.getInitialProps = async ctx => {
    return { Host: ctx.req.headers.Host }
};

export default Payment

Une autre façon de faire est d'utiliser le composant head de next.js: https://nextjs.org/docs/api-reference/next/head

<Head>
        <title>My page title</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
      </Head>
0
eroll.maxhuni

Vous devriez lire la différence entre JS dans node.js et JS dans Browser. Dans node.js, vous n'avez pas d'API DOM (window, document, document.getElementById, ...), la chose ne peut être que lorsque votre HTML est rendu dans une chose appelée fenêtres de navigateurs. Alors next.js utilise node.js pour exécuter le code JS et prend le résultat pour rendre le fichier HTML. Mais dans node.js, rien n'est Windows de Browser.

Mon anglais est assez mauvais. Mais j'espère que cette réponse vous sera utile.

0
Do Anh Bon