¿Cuál es el equivalente a ng-if en react.js?


81

Estoy reaccionando al usar angular y estoy tratando de encontrar una buena alternativa de reacción a la directiva ng-if de angular donde renderizo o no renderizo un elemento basado en una condición. Tome este código, por ejemplo. Estoy usando mecanografiado (tsx) por cierto, pero eso no debería importar mucho.

"use strict";

import * as React from 'react';

interface MyProps {showMe: Boolean}
interface MyState {}

class Button extends React.Component <MyProps, MyState>{
  constructor(props){
    super(props);
    this.state = {};
  }

  render(){
    let button;
    if (this.props.showMe === true){
       button = (
        <button type="submit" className="btn nav-btn-red">SIGN UP</button>
      )
    } else {
      button = null;
    }
    return button;

}
}
export default Button;

Esta solución funciona, pero ¿hay alguna otra forma que se utilice generalmente para lograr este efecto? Solo estoy adivinando



1
El método que ha utilizado es el método correcto en reaccionar. El uso del operador ternario reducirá su código a una línea, pero la lógica seguirá siendo la misma. Puede usar una cadena nula o en blanco (solo comillas) ''cuando no desee que se representen elementos.
Kishore Barik

El documento oficial más reciente publicó algunas formas ingeniosas de hacer esto. facebook.github.io/react/docs/…
Downhillski

Respuestas:


88

¿Qué tal un operador ternario ?

render() {
  return (
    this.props.showMe ? <button type="submit" className="btn nav-btn-red">SIGN UP</button> : null
  );
}

También puede utilizar &&:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}

El bloque grande como en el comentario se puede manejar fácilmente envolviendo el JSX en ()s:

render() {
  return this.props.showMe && (
    <div className="container">
      <button type="submit" className="btn nav-btn-red">
        SIGN UP
      </button>
    </div>
  );
}

También en línea:

render() {
  return (
    <div className="container">
      {this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>}
    </div>
  );
}

6
y ¿cómo se usa para bloques de código más grandes? solo en línea?
Asqan

18
También creo que está bastante bien, pero todavía me recuerda a la fea mezcla de PHP y HTML
ilimitado101

88
Extraño Angular :(
Uday Hiwarale

2
Para mí, es mucho más limpio que los interminables trucos de ng y cuándo es mejor usar cuál. Y me encanta poder permanecer en gran parte en el espacio similar a javascript personalmente.
Samantha Atkins

1
@PatrickCyiza ¿Puede explicarnos su problema? Suena como un problema de comparación superficial.
Yuya

25

Dejo esto aquí para fines históricos, consulte mis ediciones a continuación para obtener una solución mucho mejor después de haber desarrollado en react durante un tiempo , terminé creando un componente NgIf (esto es nativo de reacción pero probablemente funcione para reaccionar)

Código:

import React, {Component} from "react";

class NgIf extends Component {
  render() {
    if (this.props.show) {
      return (
        this.props.children
      );
    } else {
      return null
    }
  }
}

export default NgIf;

Uso:

...
import NgIf from "./path/to/component"
...

class MyClass {
   render(){
      <NgIf show={this.props.show}><Text>This Gets Displayed</Text></NgIf>
   }
}

Soy nuevo en esto, por lo que probablemente se pueda mejorar, pero me ayuda en mi transición de Angular

EDITAR

Consulte las ediciones a continuación para obtener una mejor explicación una vez que tenga más experiencia

Gracias al comentario de Jay a continuación, una gran idea también es:

render() {
   <View>{this.props.value ? <Text>Yes</Text> : <Text>No</Text>}</View>
}

O

render() {
   <View>{this.props.value && <Text>Yes</Text>}</View>
}

Similar a algunas de las otras respuestas, pero funciona en línea, en lugar de usar todo el bloque / función de renderizado, no requiere un componente especial y puede usar una declaración else con el operador ternario. Además, los elementos contenidos en la instrucción if no arrojan un error si su objeto principal no existe. Es decir, si props.valueno existe, props.value.value2no arrojará un error.

Vea esta respuesta https://stackoverflow.com/a/26152067

EDITAR 2:

Según el enlace anterior ( https://stackoverflow.com/a/26152067 ) y después de mucha más experiencia desarrollando aplicaciones de reacción, la forma anterior no es la mejor manera de hacer las cosas.

Los operadores condicionales en reacción son en realidad muy fáciles de entender. Hay dos formas de hacer las cosas:

//Show if someItem
{someItem && displayThis}

//Show if else
{someItem ? displayThisIfTrue : displayThisIfFalse}

Una advertencia que podría tener es si "someItem" no es una expresión booleana. Si dice 0, react imprimirá un 0 o react native le dará un error acerca de la necesidad de ajustar "0" en un elemento de texto. Por lo general, esto no es un problema para las pruebas falsas, pero presentará un problema para las pruebas veraces. Por ejemplo:

{!someItem && displayThis} //Will work just fine if item is 0 or null or "" etc
{someItem && displayThis} //Will print the value of someItem if its not falsy

¿Mi truco de uso frecuente? dobles negativos.

{!!someItem && displayThis}

Tenga en cuenta que esto no se aplica a los operadores ternarios (myVar? True: false), ya que convierte implícitamente el resultado en una expresión booleana.


1
Me gusta esto más. Usar componentes y atributos para describir la lógica de la vista.
Jay Wick

Actualización: después de ver estas respuestas , parece que esto no es ideal.
Jay Wick

1
Siendo nuevo en esto, estoy de acuerdo, parece un buen camino a seguir. Un inconveniente con mi método que he descubierto es que todavía fallará si un elemento contenido dentro del objeto NgIf hace referencia a algo que no existe. Gracias por señalarlo
Ryan Knell

1
Realmente aprecio que lo hayas actualizado con el tiempo. Proporciona contexto, ¡gracias!
asiegf

Gracias por EDITAR 2. Mi solución preferida
TrueKojo

21

Si también tiene otros elementos, puede ajustar solo el condicional así:

render() {
  return (
    <div>Stuff</div>
    {this.props.showMe && (
      <button type="submit" className="btn nav-btn-red">SIGN UP</button>
    )}
    <div>More stuff</div>
  );
}

1
No tan limpio como algunas de las otras sugerencias, ¡pero es genial para una sola línea!
Joel Davey

11

Un poco mejor:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}

hola yo estoy tratando de hacer esto, pero tengo varios elementos en un componente y no su trabajo
user3653796

10

Solo quería agregar que *ngIfen angular no crea una instancia del componente al que está adjunto. En React, si usa una declaración if dentro de la returndeclaración, aún creará una instancia del componente aunque no se muestre. Para lograr un *ngIfcomportamiento de tipo verdadero en React, debe crear una variable que contenga el componente condicional fuera de la returndeclaración:

render() {

  const show = false

  return show
     ? <AwesomeComponent />   //still instantiated
     : null
}

render() {

  let c = null
  const show = false

  if (show) {
    c = <AwesomeComponent />   //not instantiated
  }
  return c
}

¡Gracias esto me ayudó!
Stephen

4

Puedo pensar en al menos tres formas diferentes de simular la funcionalidad ng-if en React

  • Si
  • cambiar
  • IIFE (expresión de función invocada inmediatamente)

Puede leer la publicación aquí: Angular's ng-if Equivalent In a React Component

Básicamente, quieres hacer algo como esto:

var IfDemoComponent = React.createClass({
  render: function() {
    var el = null;
    if (this.props.showMe) {
      el = (
        <div>
          I am only included in the DOM if this.props.showMe evaluates to true.
        </div>
      );
    }
   return el;
  }
});

Gracias, esto me desbloqueó completamente, ¡salvó el día! Muchas gracias!
Stephen

4

false, null, undefined, Y trueson niños válidos. Simplemente no renderizan. Estas expresiones JSX se renderizarán todas como lo mismo:

Entonces puedes probar esto

const conditional=({condition,someArray})=>{
     return(
        <div>
          {condition && <Header /> // condition being boolean} 
          {someArray.length>0 && <Content />}
        </div>
      )
}

esto puede ser útil para renderizar condicionalmente elementos de React. Este JSX solo muestra una condición if es verdadera y solo se procesará si someArray.length> 0


4

No me gusta tener muchos operadores ternarios en el código. Por eso hice una biblioteca con un par de componentes útiles. "RcIf"

  <RcIf if={condition} >
    <h1>I no longer miss ngif</h1>
  </RcIf>
  <RcIf if={othercondition} >
    <h1>I no longer miss v-if</h1>
    <RcElse>
      <h1>I love react</h1>
    </RcElse>
  </RcIf>

Puedes instalarlo desde npm

https://www.npmjs.com/package/rc-if


3

Soy el creador de Tersus-jsx.macro y creo que este módulo proporciona exactamente lo que se necesita para esta pregunta.

En lugar de mezclar expresiones JSX y ES6 para lograr ng-if o ng-repeat, esta macro permite hacer las cosas de la misma manera que en AngularJS para React JSX, por ejemplo, para ng-if:

<div>
  <button
    tj-if={a === 0}
    id="gotoA"
    className="link"
    onClick={clicking}
  />
</div>

que es equivalente a

<div>
  {(a === 0) && (
    <button
      id="gotoA"
      className="link"
      onClick={clicking}
    />
  )}
</div>

Dado que la última versión de create-react-app soporta Babel-Macro desde el primer momento, todo lo que necesita hacer es instalar npm este módulo, envolver el retorno de renderizado con "tersus" y comenzar a asignar esos accesorios.

Puede instalar esto desde: https://www.npmjs.com/package/tersus-jsx.macro


¡Gran paquete!
secavfr

2

También vengo de un fondo angular y estaba buscando un trazador de líneas simple para mostrar la etiqueta si la variable tenía algún elemento. Esto funcionó para mí:

<div className="comic_creators">
    {c.creators.available > 0 ? <h4>Creators</h4> : null }
    {c.creators.items.map((creator,key) =>
        <Creator creator={creator} key={key}></Creator>
    )}
</div>

0

Acabo de crear un método para tomar la expresión y otros dos argumentos como plantilla en caso de que la expresión sea la verdad y la otra sea una opción else template

export function rif(exp, template, elseTemplate = null) {
    if (exp) {
        return template;
    } else {
        return elseTemplate;
    }
}

y lo uso así

import { rif } from '../utilities';

...
render() {
        return (
            <main role="main" className="container">

                {rif(
                    this.movies.length > 0,
                    <p>Showing {this.movies.length} movies. </p>,
                    <p>There are no movies..</p>
                )}
            </main>
        );
    }

0

Personalmente me gusta usar getters, es limpio y asegura reactividad:

get toBeDisplayed(){
  const { someLogicState } = this.state;
  if(someLogicState)
    return (
      <div>
        Hi, world !
      </div>
    );
  else
    return null;
}

render(){
  return (<div>{this.toBeDisplayed}</div>);
}

0

Estoy trabajando tanto angular como reacciono. Creo que angulargestiona bien la condición lógica a través de diferentes directivas.

En reactjseste enfoque funciona de manera diferente.

Puede usar if elsecondición a partir returnde render functiono ternary operator.

Con si mas

  render(){
    
    const auth = true;
    
    if(!auth)
      return(
      <div className="ps-checkout__login">
        <div className="d-flex flex-row">
            <div className="p-2"><img src="../../../static/img/return-customer.png"></img> 
             Returning Customer?</div>
            <div className="p-2"> 
                <Link href="/account/login">
                    <a>                            
                        Click here to login
                    </a>
                </Link>
            </div>
        </div>
    </div>
    )
  else return null;
    }

Con operador ternario

{ auth?
    (<div className="ps-checkout__login">
        <div className="d-flex flex-row">
            <div className="p-2"><img src="../../../static/img/return-customer.png"></img> 
            Returning Customer?</div>
            <div className="p-2"> 
                <Link href="/account/login">
                    <a>                            
                        Click here to login
                    </a>
                </Link>
            </div>
        </div>
    </div>):null } 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.