Was ist das Äquivalent zu ng-if in react.js?

80

Ich werde mit der Verwendung von Angular reagieren und versuche, eine gute Reaktionsalternative zur ng-if-Direktive von Angular zu finden, bei der ich ein Element basierend auf einer Bedingung rendere oder nicht rendere. Nehmen Sie zum Beispiel diesen Code. Ich benutze übrigens Typoskript (tsx), aber das sollte nicht viel ausmachen.

"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;

Diese Lösung funktioniert, aber gibt es einen anderen Weg, der im Allgemeinen verwendet wird, um diesen Effekt zu erzielen? Ich rate nur

Ceckenrode
quelle
1
Die Methode, die Sie verwendet haben, ist die richtige Reaktionsmethode. Wenn Sie den ternären Operator verwenden, wird Ihr Code auf eine Zeile reduziert, die Logik bleibt jedoch unverändert. Sie können eine Null- oder Leerzeichenfolge (nur Anführungszeichen) verwenden, ''wenn keine Elemente gerendert werden sollen.
Kishore Barik
Das neueste offizielle Dokument hat einige nette Möglichkeiten veröffentlicht, dies zu tun. facebook.github.io/react/docs/…
Downhillski

Antworten:

86

Wie wäre es mit einem ternären Operator ?

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

Sie können auch verwenden &&:

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

Ein großer Block wie im Kommentar kann einfach behandelt werden, indem die JSX in ()s eingeschlossen wird:

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

Auch inline:

render() {
  return (
    <div className="container">
      {this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>}
    </div>
  );
}
Yuya
quelle
6
und wie für größere Codeblöcke zu verwenden? nur inline?
Asqan
18
Ich denke auch, dass es ganz okay ist, aber es erinnert mich immer noch an die hässliche PHP & HTML-Mischung
unbegrenzt101
85
Ich vermisse Angular :(
Uday Hiwarale
2
Für mich ist es viel sauberer als die endlosen ng Hacks und wann es am besten ist, welche zu verwenden. Und ich liebe es, persönlich größtenteils im Javascript-Bereich bleiben zu können.
Samantha Atkins
1
@PatrickCyiza Können Sie Ihr Problem näher erläutern? Klingt nach einem flachen Vergleichsproblem.
Yuya
24

Ich lasse dies aus historischen Gründen hier. Eine viel bessere Lösung finden Sie in meinen Änderungen unten, nachdem ich eine Weile in Reaktion entwickelt habe. Am Ende habe ich eine NgIf-Komponente erstellt (dies ist reaktionsnativ, funktioniert aber wahrscheinlich für Reaktion).

Code:

import React, {Component} from "react";

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

export default NgIf;

Verwendung:

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

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

Ich bin neu in diesem Bereich, kann also wahrscheinlich verbessert werden, hilft mir aber bei meinem Übergang von Angular

BEARBEITEN

Weitere Informationen finden Sie in den Änderungen unten, sobald ich mehr Erfahrung habe

Dank Jays Kommentar unten ist eine großartige Idee auch:

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

ODER

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

Ähnlich wie bei einigen anderen Antworten, funktioniert jedoch inline, anstatt den gesamten Renderblock / die gesamte Renderfunktion zu verwenden, ist keine spezielle Komponente erforderlich, und Sie können eine else-Anweisung mit dem ternären Operator verwenden. Plus-Elemente in der if-Anweisung geben keinen Fehler aus, wenn das übergeordnete Objekt nicht vorhanden ist. Dh wenn wenn props.valuenicht existiert, dannprops.value.value2 wird kein Fehler ausgegeben.

Siehe diese Antwort https://stackoverflow.com/a/26152067

EDIT 2:

Gemäß dem obigen Link ( https://stackoverflow.com/a/26152067 ) und nach viel mehr Erfahrung bei der Entwicklung von Reaktions-Apps ist dies nicht der beste Weg, um Dinge zu tun.

Bedingte Operatoren, die reagieren, sind tatsächlich sehr einfach, sich zurechtzufinden. Es gibt zwei Möglichkeiten, Dinge zu tun:

//Show if someItem
{someItem && displayThis}

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

Eine Einschränkung, die Sie möglicherweise treffen, ist, wenn "someItem" kein boolescher Ausdruck ist. Wenn Sie sagen, dass 0 "Reagieren" eine 0 druckt oder "Native reagieren", wird eine Fehlermeldung angezeigt, dass "0" in ein Textelement eingeschlossen werden muss. Dies ist normalerweise kein Problem für falsche Tests, stellt jedoch ein Problem für wahrheitsgemäße Tests dar. Zum Beispiel:

{!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

Mein oft benutzter Trick? Doppel-Negative.

{!!someItem && displayThis}

Beachten Sie, dass dies nicht für ternäre Operatoren (myVar? True: false) gilt, da das Ergebnis implizit in einen booleschen Ausdruck konvertiert wird.

Ryan Knell
quelle
1
Das gefällt mir am besten. Verwenden von Komponenten und Attributen zur Beschreibung der Ansichtslogik.
Jay Wick
Update: Nachdem Sie sich diese Antworten angesehen haben , scheint dies unideal zu sein.
Jay Wick
1
Da ich selbst neu darin bin, stimme ich zu, das scheint ein guter Weg zu sein. Ein Nachteil meiner Methode, den ich entdeckt habe, ist, dass immer noch Fehler auftreten, wenn ein im NgIf-Objekt enthaltenes Element auf etwas verweist, das nicht vorhanden ist. Vielen Dank für den Hinweis
Ryan Knell
1
Ich schätze es sehr, dass Sie es mit der Zeit aktualisiert haben. Es bietet Kontext, danke!
Asiegf
Vielen Dank für EDIT 2. Meine bevorzugte Lösung
TrueKojo
21

Wenn Sie auch andere Elemente haben, können Sie nur die Bedingung wie folgt umbrechen:

render() {
  return (
    <div>Stuff</div>
    {this.props.showMe && (
      <button type="submit" className="btn nav-btn-red">SIGN UP</button>
    )}
    <div>More stuff</div>
  );
}
lundhjem
quelle
1
Nicht so sauber wie einige der anderen Vorschläge, aber großartig für einen Einzeiler!
Joel Davey
11

Ein bisschen schöner:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}
Sodoku
quelle
Hallo, ich versuche dies zu tun, aber ich habe mehrere Elemente in einer Komponente und es funktioniert nicht
user3653796
9

Ich wollte nur hinzufügen, dass *ngIfin eckig nicht die Komponente instanziiert wird, an die es angehängt ist. Wenn Sie in React eine if-Anweisung innerhalb der returnAnweisung verwenden, wird die Komponente trotzdem instanziiert, obwohl sie nicht angezeigt wird. Um *ngIfin React ein echtes Typverhalten zu erzielen , müssen Sie eine Variable erstellen, die die bedingte Komponente außerhalb der returnAnweisung enthält:

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
}
Umair Ansari
quelle
Danke das hat mir geholfen!
Stephen
4

Ich kann mir mindestens drei verschiedene Möglichkeiten vorstellen, um die ng-if-Funktionalität in React zu simulieren

  • wenn
  • Schalter
  • IIFE (sofort aufgerufener Funktionsausdruck)

Sie können den Beitrag hier lesen: Angulars ng-if-Äquivalent in einer Reaktionskomponente

Grundsätzlich möchten Sie so etwas tun:

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;
  }
});
Web Code Coach
quelle
Danke das hat mich komplett entsperrt, den Tag gerettet! Ich danke dir sehr!
Stephen
4

false, null, undefined, Und truegelten Kinder. Sie rendern einfach nicht. Diese JSX-Ausdrücke werden alle auf dasselbe übertragen:

Sie können dies also versuchen

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

Dies kann nützlich sein, um React-Elemente bedingt zu rendern. Diese JSX rendert nur eine if-Bedingung und wird nur gerendert, wenn someArray.length> 0 ist

hannad rehman
quelle
4

Ich mag es nicht, viele ternäre Operatoren im Code zu haben. Deshalb habe ich eine Bibliothek mit einigen nützlichen Komponenten erstellt. "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>

Sie können es von npm installieren

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

Percho
quelle
3

Ich bin der Schöpfer von Tersus-jsx.macro und ich denke, dieses Modul bietet genau das, was für diese Frage benötigt wird.

Anstatt JSX-Ausdrücke und ES6 zu mischen, um ng-if oder ng-repeat zu erreichen, können Sie mit diesem Makro die gleichen Schritte wie in AngularJS für React JSX ausführen, z. B. für ng-if:

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

das ist äquivalent zu

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

Angesichts der Tatsache, dass die neueste Version von create-react-app Babel-Macro sofort unterstützt, müssen Sie dieses Modul nur mit npm installieren, die Render-Rückgabe mit "tersus" umschließen und mit der Zuweisung dieser Requisiten beginnen.

Sie können dies unter folgender Adresse installieren: https://www.npmjs.com/package/tersus-jsx.macro

David Yu
quelle
Tolles Paket!
6.
2

Ich komme ebenfalls aus einem eckigen Hintergrund und suchte nach einem einfachen Einzeiler, um das Tag anzuzeigen, wenn die Variable Elemente enthält. Das hat bei mir funktioniert:

<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>
Naguib Ihab
quelle
0

Ich erstelle nur eine Methode, um Ausdruck und zwei weitere Argumente als Vorlage zu verwenden, falls der Ausdruck wahr und das andere eine Option für eine andere Vorlage ist

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

und ich benutze es so

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>
        );
    }
malbarmavi
quelle
0

Persönlich benutze ich gerne Getter, es ist sauber und gewährleistet Reaktivität:

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

render(){
  return (<div>{this.toBeDisplayed}</div>);
}
Il Saggio Vecchino
quelle
0

Ich arbeite sowohl eckig als auch reagiere. Ich denkeangular , logische Bedingungen durch verschiedene Anweisungen gut zu verwalten.

Im reactjs diesem Ansatz arbeiten Sie anders.

Sie können verwenden if elseZustand als returnder render functionoder ternary operator.

Mit wenn sonst

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

Mit ternärem Operator

{ 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 } 
Majedur Rahaman
quelle