Explorer les défis du rendu conditionnel dans les composants personnalisés React
P粉301523298
P粉301523298 2023-08-18 15:58:43
0
2
590
<p>Je rencontre un problème avec le rendu conditionnel dans un composant personnalisé de mon application React. J'ai travaillé sur la création d'un composant personnalisé pour le rendu conditionnel qui restitue le contenu uniquement lorsque certaines conditions sont remplies. Voici mon code actuel : </p> <pre class="brush:js;toolbar:false;">importer React depuis 'react'; function ConditionalRenderComponent({ condition, enfants }) { retour ( <div> {état et enfants} </div> ); } exporter le ConditionalRenderComponent par défaut ; ≪/pré> <p>Lors de l'utilisation de ce composant personnalisé, j'ai remarqué que le contenu passait par l'attribut <code>children</code> même lorsque <code>condition</code> consulté et exécuté. Ceci est différent du comportement de l'utilisation de <code>condition && <div></div></code> directement sans composant personnalisé, où la condition est <code>false</code> L'accès au contenu est correctement bloqué. </p> <p><strong>Voici comment j'utilise les composants personnalisés :</strong></p> <pre class="brush:js;toolbar:false;">importer React, { useState, useEffect } depuis 'react'; importer ConditionalRenderComponent depuis './ConditionalRenderComponent' ; fonction App() { const [userData, setUserData] = useState(null); const isLoggedIn = userData !== null; useEffect(() => { setTimeout(() => { setUserData({ nom d'utilisateur : 'john_doe', e-mail : 'john@example.com' }); }, 1000); }, []); retour ( <div> <h1>Bienvenue dans mon application</h1> <ConditionalRenderComponent condition={isLoggedIn}> <div> <p>Bonjour, {userData.username} ! </p> <p>Votre e-mail : {userData.email}</p> </div> </ConditionalRenderComponent> {!isLoggedIn && <p>Veuillez vous connecter pour accéder aux données utilisateur. </p>} </div> ); } exporter l'application par défaut ; ≪/pré> <p>Dans l'exemple ci-dessus, <code>userData</code> est initialement <code>null</code> et est ensuite renseigné avec les données récupérées du serveur. La condition <code>isLoggedIn</code> dépend du fait que <code>userData</code> </p> <p>Cependant, même si la condition <code>isLoggedIn</code> est <code>false</code> (avant d'obtenir les données), le contenu de <code>ConditionalRenderComponent</code> pour accéder et afficher <code>userData</code>. Cela entraîne le message d'erreur : "TypeError : Impossible de lire les propriétés de null (lecture de 'nom d'utilisateur')". </p> <p><strong>Comparaison avec le rendu conditionnel standard : </strong></p> <p>Voici une comparaison du comportement en utilisant l'approche standard <code>condition && <pre class="brush:js;toolbar:false;">// Rendu conditionnel standard {isLoggedIn && <div> <p>Bonjour, {userData.username} ! </p> <p>Votre e-mail : {userData.email}</p> </div> )} ≪/pré> <p>Comme indiqué dans le code ci-dessus, l'utilisation de méthodes standard bloque correctement l'accès à la valeur de <code>userData</code> lorsque la condition est <code>false</code>. </p> <p>Je ne sais pas pourquoi cette différence de comportement se produit lors de l'utilisation d'un composant personnalisé avec l'attribut <code>children</code> J'ai essayé de déboguer et de chercher des solutions mais je n'ai pas encore trouvé de réponse claire. </p> <p> Toute idée ou suggestion sur la raison pour laquelle cela pourrait se produire et sur la façon de modifier le composant personnalisé pour obtenir le comportement de rendu conditionnel attendu pour l'attribut <code>children</code> </p> <p>Merci d'avance pour votre aide ! </p>
P粉301523298
P粉301523298

répondre à tous(2)
P粉533898694

Pourquoi cela arrive-t-il ?

Je pense donc que la raison pour laquelle cela se produit est que, dans le composant ConditionalRenderComponent, l'élément enfant lui est transmis en tant qu'attribut (comme un paramètre à une fonction). Les expressions JSX sont évaluées comme arguments des fonctions.

Cela signifie que même si condition est fausse, condition为false,children在传递给ConditionalRenderComponent sera toujours évalué avant d'être transmis à la fonction

.

Exemples faciles à comprendre

PlayStation(在你的左手)和数学试卷成绩Vous donnez un

(dans votre main droite) à un enfant et lui dites que s'il obtient plus de 90/100, il obtiendra une PlayStation.

childrenComme l'enfant peut déjà voir la PlayStation dans votre main gauche (passez

comme expression JSX), il l'utilise déjà avant que l'état ne soit vérifié.

childrenMaintenant, si vous serrez le poing, cela équivaut à passer

en fonction, et il/elle ne peut pas évaluer ce qu'il y a dans votre main gauche avant de vérifier si la condition dans votre main droite est vraie.

Solution

children。这样,您可以确保只有在condition为真时才会评估childrenNous modifions notre composant personnalisé en utilisant une fonction comme élément enfant au lieu de le rendre directement dans le composant

. De cette façon, vous vous assurez que

ne sera évalué que si condition est vraie.

Modifications apportées au ConditionalRenderComponent

function ConditionalRenderComponent({ condition, children }) {
  return (
    <div>
      {condition && children()}
    </div>
  );
}
🎜Modifications apportées au rendu ConditionalRenderComponent🎜
<ConditionalRenderComponent condition={isLoggedIn}>
        {() => (
          <div>
            <p>你好,{userData.username}!</p>
            <p>你的电子邮件:{userData.email}</p>
          </div>
        )}
</ConditionalRenderComponent>
P粉543344381

Je ne recommande pas de créer un composant pour le rendu conditionnel, mais si vous souhaitez le faire, vous pouvez utiliser le modèle de propriétés de rendu afin que la fonction ne soit appelée que lorsque la condition est vraie. Cela empêche l’expression d’être évaluée immédiatement.

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>
  );
}

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal