探討React自訂元件中的條件渲染挑戰
P粉301523298
2023-08-18 15:58:43
<p>我在我的React應用程式中的自訂元件中遇到了條件渲染的問題。我一直在努力創建一個用於條件渲染的自訂元件,只有在滿足特定條件時才渲染內容。以下是我目前的程式碼:</p>
<pre class="brush:js;toolbar:false;">import React from 'react';
function ConditionalRenderComponent({ condition, children }) {
return (
<div>
{condition && children}
</div>
);
}
export default ConditionalRenderComponent;
</pre>
<p>在使用這個自訂元件時,我注意到透過<code>children</code>屬性傳遞的內容即使<code>condition</code>為<code>false</code>時也被訪問和執行。這與直接使用<code>condition && <div></div></code>而沒有自訂元件的行為不同,後者在條件為<code>false</code>時正確地阻止了內容的存取。 </p>
<p><strong>以下是我使用自訂元件的方式:</strong></p>
<pre class="brush:js;toolbar:false;">import React, { useState, useEffect } from 'react';
import ConditionalRenderComponent from './ConditionalRenderComponent';
function App() {
const [userData, setUserData] = useState(null);
const isLoggedIn = userData !== null;
useEffect(() => {
setTimeout(() => {
setUserData({
username: 'john_doe',
email: 'john@example.com'
});
}, 1000);
}, []);
return (
<div>
<h1>歡迎來到我的應用程式</h1>
<ConditionalRenderComponent condition={isLoggedIn}>
<div>
<p>你好,{userData.username}! </p>
<p>你的信箱:{userData.email}</p>
</div>
</ConditionalRenderComponent>
{!isLoggedIn && <p>請登入以存取使用者資料。 </p>}
</div>
);
}
export default App;
</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>內部的內容<code>ConditionalRenderComponent</code>內部的內容」仍然嘗試存取和顯示<code>userData</code>。這導致錯誤訊息:「TypeError: Cannot read properties of null (reading 'username')」。 </p>
<p><strong>與標準條件渲染的比較:</strong></p>
<p>以下是使用標準的<code>condition && <div></div></code>方法的行為比較:</p>
<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。由於孩子已經可以看到你左手中的PlayStation(將
children
作為JSX表達式傳遞),他/她在檢查條件之前就已經開始使用了。現在,如果你握緊你的拳頭,相當於將
children
作為函數傳遞,他/她在檢查你右手中的條件是否為真之前無法評估左手中的內容。解決方案
我們透過使用函數作為子元素來修改我們的自訂元件,而不是直接在元件中渲染
children
。這樣,您可以確保只有在condition
為真時才會評估children
。對ConditionalRenderComponent的更改
渲染ConditionalRenderComponent的改變
我不建議為條件渲染建立一個元件,但如果你想這樣做,你可以使用渲染屬性模式,這樣只有在條件為真時才呼叫函數。這樣可以防止表達式立即被評估。