web-dev-qa-db-ja.com

next.js:ドキュメントが定義されていません

私は人々が支払うことができる支払いフォームを作成しようとしていますが、私はこのエラーを受け続けます。 document is not defined。 next.jsを使用しています。以下の私のコードを参照してください

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

Next.jsのドキュメントにアクセスするには、まずページが表示されるのを待ってから、次のように変数で取得する必要があります。

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

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

あなたはあなたが2つのことをセットアップしていることを確認する必要があります。

  1. DOMレンダリングが完了しました。
  2. 次に、関数をロードします。

ステップ1:フックisMountedを作成するこれにより、DOMが確実にレンダリングされます。

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

function RenderCompleted() {

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

    useEffect(() => {
        setMounted(true)

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

    return mounted;
}

export default RenderCompleted;

関数Payment内でフックをロードします。

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

これを行う別の方法は、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

Node.jsのJSとブラウザのJSの違いを読んでください。 node.jsにはDOM API(ウィンドウ、ドキュメント、document.getElementByIdなど)がありません。HTMLがブラウザーのウィンドウと呼ばれるものでレンダリングされた場合にのみ存在する可能性があります。したがって、next.jsはnode.jsを使用してJSコードを実行し、結果を取得してHTMLファイルをレンダリングします。しかし、node.jsでは、ブラウザのウィンドウは何もありません。

私の英語はかなり下手です。しかし、私はこの答えがあなたのために役立つことを願っています。

0
Do Anh Bon