Jaki jest odpowiednik ng-if w respond.js?

82

Mam zamiar zareagować na użycie angular i próbuję znaleźć dobrą alternatywę dla dyrektywy ng-if angulara, w której renderuję lub nie renderuję elementu na podstawie warunku. Weźmy na przykład ten kod. Przy okazji używam maszynopisu (tsx), ale to nie powinno mieć większego znaczenia.

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

To rozwiązanie działa, ale czy istnieje inny sposób, który jest powszechnie używany do osiągnięcia tego efektu? Po prostu zgaduję

ceckenrode
źródło
1
Metoda, której użyłeś, jest właściwą metodą reagowania. Użycie operatora trójargumentowego zredukuje kod do jednej linii, ale logika pozostanie taka sama. Możesz użyć null lub pustego ciągu (tylko cudzysłowy), ''jeśli nie chcesz, aby elementy były renderowane.
Kishore Barik
W najnowszym oficjalnym dokumencie zamieszczono kilka ciekawych sposobów na zrobienie tego. facebook.github.io/react/docs/…
Downhillski

Odpowiedzi:

89

A co z operatorem trójskładnikowym ?

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

Możesz również użyć &&:

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

Duży blok, jak w komentarzu, można łatwo obsłużyć, opakowując JSX w ()s:

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

Również w treści:

render() {
  return (
    <div className="container">
      {this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>}
    </div>
  );
}
Yuya
źródło
6
i jak używać do większych bloków kodu? tylko w tekście?
Asqan
18
Myślę też, że jest całkiem w porządku, ale nadal przypomina mi brzydką mieszankę PHP i HTML
bez ograniczeń
88
Tęsknię za
Angularem
2
Dla mnie jest o wiele czystszy niż niekończące się hacki ng i kiedy najlepiej jest z nich skorzystać. Uwielbiam też osobiście przebywać w przestrzeni javascript.
Samantha Atkins
1
@PatrickCyiza Czy możesz rozwinąć swój problem? Brzmi jak płytki problem z porównaniem.
Yuya,
25

Zostawiam to tutaj ze względów historycznych, zobacz moje zmiany poniżej, aby uzyskać znacznie lepsze rozwiązanie po opracowaniu w reagowaniu przez chwilę Skończyło się na utworzeniu komponentu NgIf (jest to natywne reagowanie, ale prawdopodobnie działa do reagowania)

Kod:

import React, {Component} from "react";

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

export default NgIf;

Stosowanie:

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

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

Jestem w tym nowy, więc prawdopodobnie można to poprawić, ale pomaga mi w przejściu z Angular

EDYTOWAĆ

Zobacz zmiany poniżej, aby uzyskać lepsze wyjaśnienie, gdy miałem więcej doświadczenia

Dzięki poniższemu komentarzowi Jaya świetnym pomysłem jest również:

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

LUB

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

Podobnie jak w przypadku niektórych innych odpowiedzi, ale działa inline, zamiast używać całego bloku / funkcji renderowania, nie wymaga specjalnego komponentu i możesz użyć instrukcji else z operatorem trójskładnikowym. Elementy Plus zawarte w instrukcji if nie zgłaszają błędu, jeśli ich obiekt nadrzędny nie istnieje. To props.valueznaczy, jeśli nie istnieje, props.value.value2nie zgłosi błędu.

Zobacz tę odpowiedź https://stackoverflow.com/a/26152067

EDYCJA 2:

Zgodnie z powyższym linkiem ( https://stackoverflow.com/a/26152067 ) i po dużo większym doświadczeniu w tworzeniu aplikacji reagujących, powyższy sposób nie jest najlepszym sposobem robienia rzeczy.

Operatory warunkowe w React są w rzeczywistości bardzo łatwe do obejścia. Można to zrobić na dwa sposoby:

//Show if someItem
{someItem && displayThis}

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

Jedynym zastrzeżeniem, które możesz napotkać, jest to, że „someItem” nie jest wyrażeniem boolowskim. Jeśli jest napisane, że „0” zareaguje, wypisze 0 lub „zareaguje na język natywny”, wyświetli błąd dotyczący konieczności zawinięcia „0” w element tekstowy. Zwykle nie stanowi to problemu w przypadku fałszywych testów, ale będzie stanowić problem w przypadku testów zgodnych z prawdą. Na przykład:

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

Moja często używana sztuczka? podwójne negatywy.

{!!someItem && displayThis}

Zauważ, że nie dotyczy to operatorów trójskładnikowych (myVar? True: false), ponieważ niejawnie konwertuje wynik na wyrażenie boolowskie.

Ryan Knell
źródło
1
To mi się najbardziej podoba. Używanie komponentów i atrybutów do opisu logiki widoku.
Jay Wick,
Aktualizacja: po zapoznaniu się z tymi odpowiedziami wydaje się, że jest to nieidealne.
Jay Wick,
1
Jestem w tym nowy i zgadzam się, że to dobry sposób. Jedną z wad mojej metody, którą odkryłem, jest to, że nadal będzie wyświetlać błąd, jeśli element zawarty w obiekcie NgIf odwołuje się do czegoś, co nie istnieje. Dzięki za zwrócenie uwagi
Ryan Knell
1
Naprawdę doceniam to, że z czasem go zaktualizowałeś. Zawiera kontekst, dziękuję!
asiegf
Dzięki za
EDYCJĘ
21

Jeśli masz też inne elementy, możesz zawinąć tylko warunek w ten sposób:

render() {
  return (
    <div>Stuff</div>
    {this.props.showMe && (
      <button type="submit" className="btn nav-btn-red">SIGN UP</button>
    )}
    <div>More stuff</div>
  );
}
lundhjem
źródło
1
Nie tak czysty, jak niektóre inne sugestie, ale świetnie nadaje się do jednej wkładki!
Joel Davey,
11

Nieco ładniej:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}
sodoku
źródło
cześć próbuję to zrobić, ale mam kilka elementów w jednym komponencie i nie działa
user3653796
10

Chciałem tylko dodać, że *ngIfw angular nie tworzy instancji komponentu, do którego jest dołączony. W Reakcie, jeśli użyjesz instrukcji if w returninstrukcji, nadal utworzy instancję komponentu, mimo że nie jest wyświetlany. Aby uzyskać prawdziwe *ngIfzachowanie typu w Reakcie, musisz utworzyć zmienną, która przechowuje składnik warunkowy poza returninstrukcją:

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
źródło
4

Przychodzą mi do głowy przynajmniej trzy różne sposoby symulacji funkcjonalności ng-if w React

  • gdyby
  • przełącznik
  • IIFE (natychmiast wywołane wyrażenie funkcyjne)

Możesz przeczytać post tutaj: Angular's ng-if Equivalent In a React Component

Zasadniczo chcesz zrobić coś takiego:

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;
  }
});
Trener kodu internetowego
źródło
Dzięki temu całkowicie mnie odblokował, uratował dzień! Dziękuję bardzo!
Stephen,
4

false, null, undefined, I truesą ważne dla dzieci. Po prostu się nie renderują. Te wyrażenia JSX będą renderować to samo:

Więc możesz spróbować tego

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

może to być przydatne do warunkowego renderowania elementów React. Ten JSX renderuje tylko warunek if jest prawdziwy i będzie renderowany tylko wtedy, gdy someArray.length> 0

hannad rehman
źródło
4

Nie lubię mieć wielu operatorów trójskładnikowych w kodzie. Dlatego stworzyłem bibliotekę z kilkoma przydatnymi komponentami. „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>

Możesz go zainstalować z npm

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

percho
źródło
3

Jestem twórcą Tersus-jsx.macro i myślę, że ten moduł zapewnia dokładnie to, czego potrzeba do tego pytania.

Zamiast mieszać wyrażenia JSX i ES6 w celu uzyskania ng-if lub ng-repeat, to makro pozwala robić rzeczy w taki sam sposób, jak w AngularJS for React JSX, np. Dla ng-if:

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

co jest równoważne

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

Biorąc pod uwagę, że najnowsza wersja aplikacji create-react-app obsługuje Babel-Macro po wyjęciu z pudełka, wszystko, co musisz zrobić, to zainstalować ten moduł npm, zawinąć wynik renderowania za pomocą "tersus" i rozpocząć przypisywanie tych właściwości.

Możesz to zainstalować z: https://www.npmjs.com/package/tersus-jsx.macro

David Yu
źródło
Świetny pakiet!
secavfr
2

Pochodzę również z kanciastego tła i szukałem prostego jednego linera, aby pokazać tag, jeśli zmienna ma jakieś elementy. To zadziałało dla mnie:

<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
źródło
0

Po prostu tworzę metodę, która przyjmuje wyrażenie i dwa inne argumenty jako szablon w przypadku, gdy wyrażenie prawda, a drugi jest szablonem opcji else

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

i używam tego w ten sposób

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
źródło
0

Osobiście lubię używać getterów, jest czysty i zapewnia reaktywność:

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
źródło
0

Pracuję zarówno pod kątem, jak i reaguję. Myślę, że angularładnie zarządzam stanem logicznym za pomocą różnych dyrektyw.

W reactjstym podejściu działa inaczej.

Możesz użyć if elsewarunku returnz render functionlub ternary operator.

Jeśli jeszcze

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

Z operatorem trójskładnikowym

{ 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
źródło