アプリケーションに、URLハッシュフラグメントの認証プロセスからアクセストークンを受け取るコールバックルートがあります。 解析してreduxストアに保存したいのですが。 次へ切り替える前にwindow.location.hash
を通過していましたが、ページがサーバー側でレンダリングされる場合は使用できません(ハッシュフラグメントもサーバーに送信されないため、そこで解析できません) )。
一部のコードをクライアント側でのみ実行するように制限する方法はありますか? または、これを達成する他の方法はありますか?
@vanniewelt :動的にインポートされた非同期コンポーネントがクライアントに読み込まれ、すべてのクライアント側ロジックをそこに配置できます。
また、ComponentWillReceivePropsライフサイクルは、サーバー側にいる間、小道具でリクエストを受け取ります。
この変数が存在するかどうかを確認し、クライアントコードを挿入できます。
libにウィンドウ変数が必要な場合は、動的インポートを使用することをお勧めします。
https://github.com/zeit/next.js/tree/v3-beta/examples/with-dynamic-import
ReactのcomponentDidMount
ライフサイクルメソッドを使用することもできます。 サーバーサイドとは呼ばれません。
@vannieweltいつでもprocess.browser
見ることができます..
if (process.browser) {
// client-side-only code
}
@Timerによる編集:
@vannieweltいつでもtypeof window
見ることができます..
if (typeof window !== 'undefined') {
// client-side-only code
}
はい、しかしそれは最善のアプローチではありません。
ユーザーが認証されているかどうかを確認したいとします。その確認をクライアント側でのみ実行したいのは、いくつかの理由があります。その1つは、JWTをlocalStorageに保存していて、Cookieに保存したくないためです。
したがって、この場合、最初のページで次のようにロードします。
if (process.browser) {
// client-side-only code
}
スコープ内のコードは、クライアント上ではなくサーバー上ではなく、まったく実行されません。クライアントからルート変更がトリガーされた場合にのみ実行されます。
@sarkistltそのコードが配置されている場所によっては、正しい場合もあります。
そのコードがサーバー上で実行された場合、実行は// client-side-only code
到達しません。 そのコードがクライアントで実行されると、実行// client-side-only code
達します。
それは質問に対する有効な答えのようです:
一部のコードをクライアント側でのみ実行するように制限する方法はありますか?
@sarkistlt componentDidMount
はクライアント側でのみ実行され、 componentWillMount
はクライアント側とサーバー側の両方で実行されます。
@sarkistlt https://reactjs.org/docs/react-component.html#componentwillmount
これは、サーバーレンダリングで呼び出される唯一のライフサイクルフックです。
私は何度もそれをしました、あなたはcomponentWillMount
をcomponentDidMount
と混同しています。
@sergiodxaは実際にあなたが正しい、ちょうどテストを実行しました。 ありがとう!
@sergiodxa componentWillMount
のリンクがhttps://reactjs.org/docs/react-component.html#unsafe_componentwillmountに変更され
ComponentDidMount
内のクライアント側ライブラリであるmapbox-gl
モジュールが必要で、醜いエラーReferenceError: self is not defined
を取り除きました。
コンポーネントがサーバー上でまだ処理されようとしているため(正確に何をしようとしているのかわかりません)、 componentDidMount
を使用してMapboxを作成できませんでした(@elaichと同じ問題が発生しました) )。
@ aga5tyaによって提案された動的インポートを使用することでうまくいきました🎉。
@vanniewelt :動的にインポートされた非同期コンポーネントがクライアントに読み込まれ、すべてのクライアント側ロジックをそこに配置できます。
また、ComponentWillReceivePropsライフサイクルは、サーバー側にいる間、小道具でリクエストを受け取ります。
この変数が存在するかどうかを確認し、クライアントコードを挿入できます。libにウィンドウ変数が必要な場合は、動的インポートを使用することをお勧めします。
https://github.com/zeit/next.js/tree/v3-beta/examples/with-dynamic-import
解決策を探してこのスレッドに遭遇した人のために。 上記の[動的インポート]リンクが壊れています。 更新されており、 DynamicImportsにあります。
常にクライアントで実行されることになっているコンポーネントがあり、動的インポートを使用したくない場合(たとえば、ユーザーはそれらを使用する必要があることを忘れることができます)、フック(または同等のcomponentDidMount
)を使用できます
import React, { useEffect, useState } from 'react'
function CreateInteraction ({ input }) {
const [isComponentMounted, setIsComponentMounted] = useState(false)
useEffect(() => setIsComponentMounted(true), [])
if(!isComponentMounted) {
return null
}
return <h1>I'm only executed on the client!</h1>
}
すでに良い答えをいくつか追加するだけです。私の現在のプロジェクトは、両方向で多くの条件付きレンダリングを実行するため、このためのコンポーネントを使用します。
import React, { useEffect, useState } from "react";
export interface ConditionallyRenderProps {
client?: boolean;
server?: boolean;
}
const ConditionallyRender: React.FC<ConditionallyRenderProps> = (props) => {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => setIsMounted(true), []);
if(!isMounted && props.client) {
return null;
}
if(isMounted && props.server) {
return null;
}
return props.children as React.ReactElement;
};
export default ConditionallyRender;
そして、それを次のように使用します。
<Layout>
<ConditionallyRender server>
<p>This is rendered only on server.</p>
</ConditionallyRender>
<ConditionallyRender client>
<p>This is rendered only on client.</p>
</ConditionallyRender>
</Layout>
ブラウザAPIにアクセスするライブラリを使用している場合は、2番目の引数としてSSR = falseを使用してモジュールを動的にインポートできます。
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)
https://nextjs.org/docs/advanced-features/dynamic-import
ブラウザAPIにアクセスするライブラリを使用している場合は、2番目の引数としてSSR = falseを使用してモジュールを動的にインポートできます。
const DynamicComponentWithNoSSR = dynamic( () => import('../components/hello3'), { ssr: false } )
https://nextjs.org/docs/advanced-features/dynamic-import
@ yashwant-dangiコードを見ている人に「動的」インポートを使用する場合も、このインポートを追加する必要があります。
import dynamic from 'next/dynamic'
@Timerコメントhttps://github.com/vercel/next.js/issues/2473#issuecomment-362119102を編集したことに気付きました。これは、元のコメントと編集内容を反映するために再度編集しました。
process.browser
だけでなくtypeof window !== 'undefined'
を使用する必要があるのはなぜですか? より冗長なので、ここで理由がない場合は、 process.browser
を使用することをお勧めします。process.browserだけでなくtypeofwindow!== 'undefined'を使用する必要があるのはなぜですか? より冗長なので、ここで理由がない場合は、process.browserを使用することをお勧めします。
process.browser
は非標準であり、webpack環境でのみ使用できます。つまり、将来的に破損する可能性があります。たとえば、webpack 5はprocess
ポリフィルしなくなります。
最も参考になるコメント
@vannieweltいつでも
process.browser
見ることができます..@Timerによる編集:
@vannieweltいつでも
typeof window
見ることができます..