React カスタム コンポーネントの条件付きレンダリングの課題を探る
P粉301523298
2023-08-18 15:58:43
<p>React アプリケーションのカスタム コンポーネントでの条件付きレンダリングで問題が発生しています。私は、特定の条件が満たされた場合にのみコンテンツをレンダリングする条件付きレンダリング用のカスタム コンポーネントの作成に取り組んできました。これが私の現在のコードです: </p>
<pre class="brush:js;toolbar:false;">React を 'react' からインポートします。
function ConditionalRenderComponent({ 条件, 子 }) {
戻る (
<div>
{条件と子供たち}
</div>
);
}
デフォルトのConditionalRenderComponentをエクスポートします。
</pre>
<p>このカスタム コンポーネントを使用しているときに、<code>condition</code> が <code>false</code> の場合でも、コンテンツが <code>children</code> 属性を通過していることに気付きました。アクセスされて実行されます。これは、条件が <code>false</code> の場合、カスタム コンポーネントを使用せずに <code>condition && <div></div></code> を直接使用する動作とは異なります。コンテンツへのアクセスは適切にブロックされます。 </p>
<p><strong>カスタム コンポーネントの使用方法は次のとおりです。</strong></p>
<pre class="brush:js;toolbar:false;">import React, { useState, useEffect } from 'react';
'./ConditionalRenderComponent' から ConditionalRenderComponent をインポートします。
関数 App() {
const [userData, setUserData] = useState(null);
const isLoggedIn = userData !== null;
useEffect(() => {
setTimeout(() => {
setUserData({
ユーザー名: 'john_doe'、
電子メール: 'john@example.com'
});
}, 1000);
}、[]);
戻る (
<div>
<h1>私のアプリへようこそ</h1>
<ConditionalRenderComponent 条件={isLoggedIn}>
<div>
<p>こんにちは、{userData.username}! </p>
<p>あなたのメールアドレス: {userData.email}</p>
</div>
</ConditionalRenderComponent>
{!isLoggedIn && <p>ユーザー データにアクセスするにはログインしてください。 </p>}
</div>
);
}
デフォルトのアプリをエクスポートします。
</pre>
<p>上記の例では、<code>userData</code> は最初は <code>null</code> ですが、後でサーバーから取得したデータが設定されます。 <code>isLoggedIn</code> 条件は、<code>userData</code> が設定されているかどうかによって異なります。 </p>
<p>ただし、<code>isLoggedIn</code> 条件が <code>false</code> (データを取得する前) であっても、<code>ConditionalRenderComponent</code> 内のコンテンツは引き続き試行します。 userData
にアクセスして表示します。これにより、「TypeError: null のプロパティを読み取れません ('username' を読み取っています)」というエラー メッセージが表示されます。 </p>
<p><strong>標準の条件付きレンダリングとの比較: </strong></p>
<p>ここでは、標準の <code>condition && <div></div></code> アプローチを使用した動作の比較を示します。
<pre class="brush:js;toolbar:false;">// 標準の条件付きレンダリング
{isLoggedIn && (
<div>
<p>こんにちは、{userData.username}! </p>
<p>あなたのメールアドレス: {userData.email}</p>
</div>
)}
</pre>
<p>上記のコードに示されているように、標準メソッドを使用すると、条件が <code>false</code> の場合、<code>userData</code> の値へのアクセスが正しく防止されます。 </p>
<p><code>children</code> 属性を持つカスタム コンポーネントを使用するときに、なぜこのような動作の違いが発生するのかわかりません。デバッグを試みて解決策を探しましたが、明確な答えはまだ見つかりません。 </p>
<p> この問題が発生する理由、および <code>children</code> 属性の予想される条件付きレンダリング動作を実現するためにカスタム コンポーネントを変更する方法に関する洞察や提案があれば、大変感謝いたします。 </p>
<p>よろしくお願いいたします。 </p>
なぜこのようなことが起こるのでしょうか?
これが起こっている理由は、
ConditionalRenderComponent
コンポーネントで、子要素が (関数の引数と同じように) プロパティとして渡されるためだと思います。 JSX 式は関数の引数として評価されます。これは、
condition
が false の場合でも、children
はConditionalRenderComponent
関数に渡される前に評価されることを意味します。わかりやすい例
あなたは子供に
PlayStation
(左手) と数学の紙のスコア
(右手) を渡し、スコアが 90 を超えていれば / と言います。 100歳なら、彼/彼女はプレイステーションを買うでしょう。子供はすでに左手に PlayStation を持っているので (
children
を JSX 式として渡します)、条件がチェックされる前にすでに PlayStation を使い始めています。ここで、こぶしを握り締めると、関数として
###解決###children
を渡すのと同じことになり、右手の条件が true かどうかを確認する前に、左手にあるものを評価することはできません。 。コンポーネント内で
childrenを直接レンダリングするのではなく、関数を子要素として使用してカスタム コンポーネントを変更します。こうすることで、
ConditionalRenderComponent への変更点
リーリーchildren
はcondition
が true の場合にのみ評価されるようになります。ConditionalRenderComponent のレンダリングの変更点
リーリー条件付きレンダリング用のコンポーネントを作成することはお勧めしませんが、そうしたい場合は、レンダリング プロパティ パターンを使用して、条件が true の場合にのみ関数が呼び出されるようにすることができます。これにより、式がすぐに評価されなくなります。
リーリー