Що еквівалентно ng-if у реакції.js?


81

Я реагую на використання angular і намагаюся зрозуміти хорошу альтернативу реакції ng-if директиви angular, де я відображаю або не відображаю елемент на основі умови. Візьмемо для прикладу цей код. Я використовую машинопис (tsx) до речі, але це не повинно мати великого значення.

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

Це рішення працює, але чи існує інший спосіб, який зазвичай використовується для досягнення цього ефекту? Я просто начебто здогадуюсь



1
Метод, який ви використовували, є правильним методом реагування. Використання тернарного оператора зменшить ваш код до одного рядка, але логіка все одно буде незмінною. Ви можете використовувати нульовий або порожній рядок (лише лапки), ''коли не хочете, щоб елементи відображались.
Kishore Barik,

Останній офіційний документ опублікував кілька акуратних способів зробити це. facebook.github.io/react/docs/…
Даунхілскі

Відповіді:


88

Як щодо тернарного оператора ?

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

Ви також можете використовувати &&:

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

Великий блок, як у коментарі, можна легко обробити, обернувши JSX у ()s:

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

Також вбудовано:

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

6
і як використовувати для більших блоків коду? просто вбудований?
Аскан,

18
Я також думаю, що це цілком нормально, але все одно нагадує мені потворну суміш PHP і HTML
необмежено101

88
Я сумую за Angular :(
Удай Хіварале,

2
Для мене це набагато чистіше, ніж нескінченні нг-хаки, і коли найкраще використовувати які. І мені подобається можливість значною мірою залишатися в просторі, пристосованому до javascript, особисто.
Саманта Еткінс

1
@PatrickCyiza Чи можете Ви детальніше розповісти про свою проблему? Звучить як неглибока проблема порівняння.
Юя

25

Я залишаю це тут для історичних цілей, будь ласка, перегляньте мої редагування нижче для набагато кращого рішення, після того, як я деякий час розробив реакцію, і в кінцевому підсумку створив компонент NgIf (це рідна реакція, але, можливо, працює для реакції)

Код:

import React, {Component} from "react";

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

export default NgIf;

Використання:

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

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

Я новачок у цьому, тому, мабуть, можна вдосконалити, але допомагає мені у переході від Angular

РЕДАГУВАТИ

Див. Редакції нижче для кращого пояснення, коли я мав більше досвіду

Завдяки коментарю Джея нижче, чудова ідея також:

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

АБО

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

Подібно до деяких інших відповідей, але працює вбудовано, замість того, щоб використовувати весь блок / функцію візуалізації, не вимагає спеціального компонента, і ви можете використовувати оператор else з тернарним оператором. Плюс елементи, що містяться в операторі if, не видають помилки, якщо їх батьківський об'єкт не існує. Тобто якщо якщо props.valueне існує, то props.value.value2не видасть помилки.

Дивіться цю відповідь https://stackoverflow.com/a/26152067

РЕДАКТУВАТИ 2:

Відповідно до вищевказаного посилання ( https://stackoverflow.com/a/26152067 ) і після набагато більше досвіду у розробці програм для реагування, вищезазначений спосіб - не найкращий спосіб зробити щось.

Умовні оператори в реакції насправді дуже легко розібратися. Є два способи зробити щось:

//Show if someItem
{someItem && displayThis}

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

Одне застереження, яке ви могли б вразити, це те, що "someItem" не є логічним виразом. Якщо це "0", реакція надрукує 0 або "рідний" відповідь видасть вам помилку про необхідність обернути "0" у текстовий елемент. Зазвичай це не є проблемою для тестів на хибність, але це представляє проблему для істинних тестів. Наприклад:

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

Мій часто використовуваний трюк? подвійні негативи.

{!!someItem && displayThis}

Зверніть увагу, що це не застосовується до тернарних операторів (myVar? True: false), оскільки він неявно перетворює результат у логічний вираз.


1
Мені це подобається найбільше. Використання компонентів та атрибутів для опису логіки перегляду.
Jay Wick

Оновлення: переглянувши ці відповіді , виявляється, це незвично.
Jay Wick

1
Будучи новим у цьому, я погоджуюсь, це виглядає як хороший шлях. Один недолік мого методу, який я виявив, полягає в тому, що він все одно буде помилятися, якщо елемент, що міститься в об'єкті NgIf, посилається на щось, що не існує. Дякуємо, що вказали на це
Райан Кнелл

1
Я дуже вдячний, що ви з часом його оновили. Це забезпечує контекст, дякую!
asiegf

Дякуємо за EDIT 2. Моє найкраще рішення
TrueKojo

21

Якщо у вас є й інші елементи, ви можете обернути лише умовні так:

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

1
Не такий чистий, як деякі інші пропозиції, але чудовий для одного лайнера!
Джоел Дейві

11

Трохи приємніше:

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

привіт, я намагаюся це зробити, але у мене є кілька елементів в одному компоненті, і він не працює
user3653796

10

Я просто хотів додати, що *ngIfв angular не створює екземпляр компонента, до якого він приєднаний. У React, якщо ви використовуєте оператор if в returnоператорі, він все одно створюватиме компонент, навіть якщо він не відображається. Щоб досягти справжньої *ngIfповедінки типу в React, вам потрібно створити змінну, яка містить умовний компонент поза returnоператором:

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
}

4

Я можу придумати принаймні три різні способи імітації функціональності ng-if у React

  • якщо
  • перемикач
  • IIFE (вираз функції, що викликається негайно)

Ви можете прочитати допис тут: Angular's ng-if еквівалент у компоненті React

В основному, ви хочете зробити щось подібне:

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

Дякую, це повністю розблокувало мене, врятувало день! Дуже дякую!
Стівен

4

false, null, undefined, І trueє дійсними дітьми. Вони просто не надають. Ці JSX-вирази відображатимуться до одного і того ж:

Тож ви можете спробувати це

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

це може бути корисно для умовної візуалізації елементів React. Цей JSX відображає лише, якщо умова є істинним, і відображатиметься, лише якщо someArray.length> 0


4

Мені не подобається мати багато кодових операторів у коді. Тому я зробив бібліотеку з парою корисних компонентів. "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>

Ви можете встановити його з npm

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


3

Я є творцем Tersus-jsx.macro, і я думаю, що цей модуль надає саме те, що потрібно для цього питання.

Замість змішування виразів JSX та ES6 для досягнення ng-if або ng-repeat, цей макрос дозволяє робити те саме, що й у AngularJS для React JSX, наприклад для ng-if:

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

що еквівалентно

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

Враховуючи те, що остання версія програми-реагування-програми підтримує Babel-Macro з коробки, все, що вам потрібно зробити, це встановити цей модуль в npm, обернути повернення рендеринга "tersus" і почати призначати ці реквізити.

Ви можете встановити це з: https://www.npmjs.com/package/tersus-jsx.macro


Чудовий пакет!
secavfr

2

Я теж з кутового фону і шукав простий вкладиш, щоб показати тег, якщо змінна має якісь елементи. Це спрацювало для мене:

<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

Я просто створюю метод, щоб взяти вираз і два інші аргументи як шаблон на випадок, якщо вираз істина, а інший є варіантом else шаблон

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

і я використовую його так

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

Особисто мені подобається користуватися геттерами, він чистий і забезпечує реактивність:

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

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

0

Я працюю і кутово, і реагую. Я думаю, що angularдобре управляю логічними умовами за допомогою різних директив.

У reactjsцьому підході працюють по-різному.

Ви можете використовувати if elseумову станом returnна render functionабо ternary operator.

Якщо інше

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

З потрійним оператором

{ 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 } 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.