É possível usar a instrução if… else… na função de renderização React?


102

Basicamente, eu tenho um componente de reação, seu render()corpo de função é o seguinte: (É o meu ideal, o que significa que atualmente não funciona)

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // note: code does not work here
            if (this.props.hasImage) <MyImage />
            else <OtherElement/>
        </div>
    )
}

Sim, este é um problema muito comum e uma ótima pergunta! Talvez uma formulação um pouco diferente e mostrando o que acontece ao executar esse código específico (também considere formatá-lo um pouco) ajudaria a esclarecer exatamente o problema.
ZekeDroid

Sim, é errado (ideal). Acabei de atualizar a pergunta para esclarecer o problema. Obrigado
Xin

1
para ruim não pode escrever se ... else in render
vijay

Respostas:


195

Não exatamente assim, mas existem soluções alternativas. Há uma seção na documentação do React sobre renderização condicional que você deve dar uma olhada. Aqui está um exemplo do que você poderia fazer usando if-else inline.

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

Você também pode lidar com isso dentro da função render, mas antes de retornar o jsx.

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

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

Também vale a pena mencionar o que ZekeDroid trouxe nos comentários. Se você está apenas verificando uma condição e não deseja renderizar uma parte específica do código que não está em conformidade, você pode usar o && operator.

  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );

15
Um truque bacana também é usar o recurso de curto-circuito do JS! Para evitar fazer algo como isTrue ? <div>Something</div> : nullvocê pode simplesmente fazerisTrue && <div>Something</div>
ZekeDroid

1
Além disso, você pode verificar o artigo a seguir para descobrir mais sobre renderizações condicionais no React além de if else.
Robin Wieruch

Eu quero lidar com a condição no loop como "data.map (item => (<tr> <td> if (item.type == 'image') {<image src =" {image.src} ">} else {{item}} </td> </tr>)) "algo assim
Vikas Chauhan

55

Na verdade, existe uma maneira de fazer exatamente o que o OP está pedindo. Basta renderizar e chamar uma função anônima como:

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

6

Você pode processar qualquer coisa usando a conditionaldeclaração como 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>
    );
  }

5

Você deve se lembrar sobre o operador TERNARY

:

então seu código será assim,

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

4

Se quiser que uma condição mostre elementos, você pode usar algo assim.

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

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

Em seguida, chame o método de ajuda dentro da função de renderização.

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

Ou você pode usar outra forma de condição dentro do retorno.

{this.props.hasImage ? <element1> : <element2>}

4

Tipo 1: If estilo de declaração

{props.hasImage &&

  <MyImage />

}


Tipo 2: If else estilo de declaração

   {props.hasImage ?

      <MyImage /> :

      <OtherElement/>

    }

2

A abreviação para uma estrutura if else funciona conforme esperado em JSX

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

Você pode encontrar outras opções nesta postagem do blog do DevNacho , mas é mais comum fazer isso com a abreviação. Se você precisa ter uma cláusula if maior, você deve escrever uma função que retorna ou o componente A ou o componente B.

por exemplo:

this.setState({overlayHovered: true});

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

Você pode desestruturar seu overlayHovered a partir de this.state se você o fornecer como parâmetro. Em seguida, execute essa função em seu método render ():

renderComponentByState(this.state)


2

Se você precisar de mais de uma condição, pode tentar

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

1

Pode ser que cheguei tarde demais. Mas espero que isso ajude alguém. Primeiro separe esses dois elementos.

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

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

Então você pode chamar essas funções da função render usando a instrução if else.

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

Isso funciona para mim. :)


1

Usei o operador ternário e está funcionando bem para mim.

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


1

Você também pode usar o operador condicional (ternário) dentro do operador condicional, caso você tenha 2 dependências diferentes.

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

1

Tente usar o caso Switch ou operador ternário

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

Isso funcionou para mim e deve funcionar para você. Experimente o operador ternário

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.