Est-il possible d'utiliser l'instruction if… else… dans la fonction de rendu React?

94

En gros, j'ai un composant de réaction, son render()corps de fonction est comme ci-dessous: (C'est mon idéal, ce qui signifie qu'il ne fonctionne pas actuellement)

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // note: code does not work here
            if (this.props.hasImage) <MyImage />
            else <OtherElement/>
        </div>
    )
}
Xin
la source
Oui, c'est un problème très courant à rencontrer et une excellente question! Peut-être que le libellé un peu différent et montrer ce qui se passe lorsque vous exécutez ce code particulier (envisagez également de le formater un peu) aiderait à résoudre exactement le problème.
ZekeDroid
Oui, c'est une mauvaise (idéale). Je viens de mettre à jour la question pour résoudre le problème. Merci
Xin
1
à mauvais ne peut pas écrire si ... else dans le rendu
vijay

Réponses:

179

Pas exactement comme ça, mais il existe des solutions de contournement. Il y a une section dans la documentation de React sur le rendu conditionnel que vous devriez jeter un coup d'œil. Voici un exemple de ce que vous pourriez faire en utilisant if-else en ligne.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

Vous pouvez également le gérer dans la fonction de rendu, mais avant de renvoyer le jsx.

if (isLoggedIn) {
  button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
  button = <LoginButton onClick={this.handleLoginClick} />;
}

return (
  <div>
    <Greeting isLoggedIn={isLoggedIn} />
    {button}
  </div>
);

Il convient également de mentionner ce que ZekeDroid a évoqué dans les commentaires. Si vous recherchez simplement une condition et que vous ne souhaitez pas rendre un morceau de code particulier qui n'est pas conforme, vous pouvez utiliser le && operator.

  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
Alexandre Angelim
la source
14
Une astuce astucieuse consiste également à utiliser la fonction de court-circuit de JS! Pour éviter de faire quelque chose comme isTrue ? <div>Something</div> : nullvous pouvez le faireisTrue && <div>Something</div>
ZekeDroid
1
De plus, vous pouvez consulter l'article suivant pour en savoir plus sur d'autres rendus conditionnels dans React en dehors de if else.
Robin Wieruch
Je veux gérer la condition dans la boucle comme "data.map (item => (<tr> <td> if (item.type == 'image') {<image src =" {image.src} ">} else {{item}} </td> </tr>)) "quelque chose comme ça
Vikas Chauhan
51

Il existe en fait un moyen de faire exactement ce que OP demande. Il suffit de rendre et d'appeler une fonction anonyme comme ceci:

render () {
  return (
    <div>
      {(() => {
        if (someCase) {
          return (
            <div>someCase</div>
          )
        } else if (otherCase) {
          return (
            <div>otherCase</div>
          )
        } else {
          return (
            <div>catch all</div>
          )
        }
      })()}
    </div>
  )
}
manncito
la source
5

Vous pouvez rendre quelque chose en utilisant la conditionaldéclaration comme if, else:

 render() {
    const price = this.state.price;
    let comp;

    if (price) {

      comp = <h1>Block for getting started with {this.state.price}</h1>

    } else {

      comp = <h1>Block for getting started.</h1>

    }

    return (
      <div>
        <div className="gettingStart">
          {comp}
        </div>
      </div>
    );
  }
Shubham Verma
la source
5

Vous devez vous souvenir de l' opérateur TERNARY

:

donc votre code sera comme ça,

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // note: code does not work here
            { 
               this.props.hasImage ?  // if has image
               <MyImage />            // return My image tag 
               :
               <OtherElement/>        // otherwise return other element  

             }
        </div>
    )
}
Mohideen bin Mohammed
la source
4

Si vous voulez qu'une condition affiche des éléments, vous pouvez utiliser quelque chose comme ceci.

renderButton() {
    if (this.state.loading) {
        return <Spinner size="small" spinnerStyle={styles.spinnerStyle} />;
    }

    return (
        <Button onPress={this.onButtonPress.bind(this)}>
            Log In
        </Button>
    );
}

Appelez ensuite la méthode d'aide à l'intérieur de la fonction de rendu.

<View style={styles.buttonStyle}>
      {this.renderButton()}
</View>

Ou vous pouvez utiliser un autre moyen de condition dans le retour.

{this.props.hasImage ? <element1> : <element2>}
Buwaneka Sudheera
la source
2

Le raccourci pour une structure if else fonctionne comme prévu dans JSX

this.props.hasImage ? <MyImage /> : <SomeotherElement>

Vous pouvez trouver d'autres options sur cet article de blog de DevNacho , mais il est plus courant de le faire avec la sténographie. Si vous avez besoin d'avoir un plus grand si l' article vous devez écrire une fonction qui renvoie ou le composant A ou B. composant

par exemple:

this.setState({overlayHovered: true});

renderComponentByState({overlayHovered}){
    if(overlayHovered) {
        return <overlayHoveredComponent />
    }else{
        return <overlayNotHoveredComponent />
    }
}

Vous pouvez déstructurer votre overlayHovered de this.state si vous le donnez comme paramètre. Exécutez ensuite cette fonction dans votre méthode render ():

renderComponentByState(this.state)

Kevin
la source
2

Si vous avez besoin de plus d'une condition, vous pouvez donc essayer ceci

https://www.npmjs.com/package/react-if-elseif-else-render

import { If, Then, ElseIf, Else } from 'react-if-elseif-else-render';

class Example extends Component {

  render() {
    var i = 3; // it will render '<p>Else</p>'
    return (
      <If condition={i == 1}>
        <Then>
          <p>Then: 1</p>
        </Then>
        <ElseIf condition={i == 2}>
          <p>ElseIf: 2</p>
        </ElseIf>
        <Else>
          <p>Else</p>
        </Else>
      </If>
    );
  }
}
Kushal Jain
la source
2

Type 1: If style de déclaration

{props.hasImage &&

  <MyImage />

}


Type 2: If else style de déclaration

   {props.hasImage ?

      <MyImage /> :

      <OtherElement/>

    }
Yuvraj Patil
la source
1

Peut-être que je suis trop tard ici. Mais j'espère que cela aiderait quelqu'un. Commencez par séparer ces deux éléments.

renderLogout(){
<div>
   <LogoutButton onClick={this.handleLogoutClick} />
<div>
}

renderLogin(){
<div>
   <LoginButton onClick={this.handleLoginClick} />
<div>
}

Ensuite, vous pouvez appeler ces fonctions à partir de la fonction de rendu en utilisant l'instruction if else.

render(){
if(this.state.result){
  return this.renderResult();
}else{
  return this.renderQuiz();
}}

Cela fonctionne pour moi. :)

Choxmi
la source
1

J'ai utilisé un opérateur ternaire et cela fonctionne très bien pour moi.

> {item.lotNum == null ? ('PDF'):(item.lotNum)}

Vinod Kumar
la source
1

Vous pouvez également utiliser un opérateur conditionnel (ternaire) dans l'opérateur conditionnel au cas où vous auriez 2 dépendances différentes.

{
(launch_success)
  ?
  <span className="bg-green-100">
    Success
  </span>
  :
  (upcoming)
    ?
    <span className="bg-teal-100">
      Upcoming
    </span>
    :
    <span className="bg-red-100">
      Failed
    </span>
}
Hasan Sefa Ozalp
la source
0

Essayez avec le boîtier Switch ou l'opérateur ternaire

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // updated code works here
            {(() => {
                        switch (this.props.hasImage) {
                            case (this.props.hasImage):
                                return <MyImage />;
                            default:
                                return (
                                   <OtherElement/>; 
                                );
                        }
                    })()}
        </div>
    )
}

Cela a fonctionné pour moi et devrait fonctionner pour vous. Essayez l' opérateur ternaire

champion-coureur
la source