Heim  >  Fragen und Antworten  >  Hauptteil

Erkundung der Herausforderungen des bedingten Renderings in benutzerdefinierten React-Komponenten

<p>Ich habe ein Problem mit dem bedingten Rendering in einer benutzerdefinierten Komponente in meiner React-Anwendung. Ich habe daran gearbeitet, eine benutzerdefinierte Komponente für bedingtes Rendering zu erstellen, die Inhalte nur dann rendert, wenn bestimmte Bedingungen erfüllt sind. Hier ist mein aktueller Code: </p> <pre class="brush:js;toolbar:false;">import React from 'react'; Funktion ConditionalRenderComponent({ Bedingung, Kinder }) { zurückkehren ( <div> {Bedingung && </div> ); } Export Standard ConditionalRenderComponent; </pre> <p>Bei der Verwendung dieser benutzerdefinierten Komponente ist mir aufgefallen, dass der Inhalt auch dann über das Attribut <code>children</code> übergeben wird, wenn <code>condition</code> abgerufen und ausgeführt werden. Dies unterscheidet sich vom Verhalten bei der direkten Verwendung von <code>condition && </div></code>, wo die Bedingung <code>false</code> ist. Der Zugriff auf die Inhalte ist ordnungsgemäß gesperrt. </p> <p><strong>So verwende ich benutzerdefinierte Komponenten:</strong></p> <pre class="brush:js;toolbar:false;">import React, { useState, useEffect } from 'react'; importiere ConditionalRenderComponent aus './ConditionalRenderComponent'; Funktion App() { const [userData, setUserData] = useState(null); const isLoggedIn = userData !== null; useEffect(() => { setTimeout(() => { setUserData({ Benutzername: 'john_doe', E-Mail: 'john@example.com' }); }, 1000); }, []); zurückkehren ( <div> <h1>Willkommen in meiner App</h1> <ConditionalRenderComponent beding={isLoggedIn}> <div> <p>Hallo, {userData.username}! </p> <p>Ihre E-Mail: {userData.email}</p> </div> </ConditionalRenderComponent> {!isLoggedIn && <p>Bitte melden Sie sich an, um auf Benutzerdaten zuzugreifen. </p>} </div> ); } Standard-App exportieren; </pre> <p>Im obigen Beispiel ist <code>userData</code> zunächst <code>null</code> und wird später mit vom Server abgerufenen Daten gefüllt. Die Bedingung <code>isLoggedIn</code> hängt davon ab, ob <code>userData</code> </p> <p>Obwohl die Bedingung <code>isLoggedIn</code> lautet (bevor die Daten abgerufen werden), versucht der Inhalt in <code>ConditionalRenderComponent</code> um auf <code>userData</code> zuzugreifen und diese anzuzeigen. Dies führt zu der Fehlermeldung: „TypeError: Eigenschaften von Null können nicht gelesen werden (‚Benutzername‘ wird gelesen)“. </p> <p><strong>Vergleich zum standardmäßigen bedingten Rendering: </strong></p> <p>Hier ist ein Vergleich des Verhaltens unter Verwendung des Standardansatzes <code>&& </div></p> <pre class="brush:js;toolbar:false;">// Standardbedingtes Rendering {isLoggedIn && ( <div> <p>Hallo, {userData.username}! </p> <p>Ihre E-Mail: {userData.email}</p> </div> )} </pre> <p>Wie im obigen Code gezeigt, blockiert die Verwendung von Standardmethoden den Zugriff auf den Wert von <code>userData</code>, wenn die Bedingung <code>false</code> ist. </p> <p>Ich bin mir nicht sicher, warum dieser Verhaltensunterschied auftritt, wenn eine benutzerdefinierte Komponente mit dem Attribut <code>children</code> verwendet wird. Ich habe versucht, Fehler zu beheben und nach Lösungen zu suchen, habe aber noch keine klare Antwort gefunden. </p> <p> Für Hinweise oder Vorschläge, warum dies passieren könnte und wie die benutzerdefinierte Komponente geändert werden kann, um das erwartete bedingte Rendering-Verhalten für das Attribut <code>children</code> zu erreichen, wären wir sehr dankbar. </p> <p>Vielen Dank im Voraus für Ihre Hilfe! </p>
P粉301523298P粉301523298451 Tage vor555

Antworte allen(2)Ich werde antworten

  • P粉533898694

    P粉5338986942023-08-19 15:04:37

    为什么会发生这种情况?

    所以我认为发生这种情况的原因是,在ConditionalRenderComponent组件中,子元素被作为属性传递给它(就像函数的参数一样)。JSX表达式被作为函数的参数进行评估。

    这意味着即使condition为false,children在传递给ConditionalRenderComponent函数之前仍然会被评估。

    易于理解的示例

    你把一个PlayStation(在你的左手)和数学试卷成绩(在你的右手)给了一个孩子,并说如果他/她的分数超过90/100,他/她就会得到PlayStation。

    由于孩子已经可以看到你左手中的PlayStation(将children作为JSX表达式传递),他/她在检查条件之前就已经开始使用了。

    现在,如果你握紧你的拳头,相当于将children作为函数传递,他/她在检查你右手中的条件是否为真之前无法评估左手中的内容。

    解决方案

    我们通过使用一个函数作为子元素来修改我们的自定义组件,而不是直接在组件中渲染children。这样,您可以确保只有在condition为真时才会评估children

    对ConditionalRenderComponent的更改

    function ConditionalRenderComponent({ condition, children }) {
      return (
        <div>
          {condition && children()}
        </div>
      );
    }

    对渲染ConditionalRenderComponent的更改

    <ConditionalRenderComponent condition={isLoggedIn}>
            {() => (
              <div>
                <p>你好,{userData.username}!</p>
                <p>你的电子邮件:{userData.email}</p>
              </div>
            )}
    </ConditionalRenderComponent>

    Antwort
    0
  • P粉543344381

    P粉5433443812023-08-19 13:02:01

    我不建议为条件渲染创建一个组件,但如果你想这样做,你可以使用渲染属性模式,这样只有在条件为真时才调用函数。这样可以防止表达式立即被评估。

    function If({ condition, render }) {
      if (!condition) return null;
    
      return render();
    }
    
    export default function App() {
      const [state, setState] = useState(null);
    
      useEffect(() => {
        wait(1000).then(() => {
          setState({ hello: "world" });
        });
      }, []);
    
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
    
          <If condition={Boolean(state)} render={() => <p>{state.hello}</p>} />
        </div>
      );
    }

    Antwort
    0
  • StornierenAntwort