私は人々が支払うことができる支払いフォームを作成しようとしていますが、私はこのエラーを受け続けます。 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
Next.jsのドキュメントにアクセスするには、まずページが表示されるのを待ってから、次のように変数で取得する必要があります。
const [_document, set_document] = React.useState(null)
React.useEffect(() => {
set_document(document)
}, [])
あなたはあなたが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>
Node.jsのJSとブラウザのJSの違いを読んでください。 node.jsにはDOM API(ウィンドウ、ドキュメント、document.getElementByIdなど)がありません。HTMLがブラウザーのウィンドウと呼ばれるものでレンダリングされた場合にのみ存在する可能性があります。したがって、next.jsはnode.jsを使用してJSコードを実行し、結果を取得してHTMLファイルをレンダリングします。しかし、node.jsでは、ブラウザのウィンドウは何もありません。
私の英語はかなり下手です。しかし、私はこの答えがあなたのために役立つことを願っています。