Soru ReactJs - Bir “If” bileşeni oluşturmak… iyi bir fikir mi?


React dokümanlarında, JSX kodunda "if" türü ifadelerinin kullanılamayacağını, JSX'in javascript içine işlenmesinden dolayı okudum, bir bekleyeceği gibi çalışmaz.

Ama bir "if" bileşeninin uygulanmasının kötü bir fikir olmasının bir nedeni var mı? İlk testlerimden iyi çalışıyor gibi görünüyor ve bu neden daha sık yapılmadığını merak ediyor?

Amacımın bir kısmı, mümkün olan en az javascript ile, tepki gelişiminin mümkün olduğunca çok, işaretlemeye dayalı olmasına izin vermektir. Bu yaklaşım benim için daha çok “veri odaklı” bir yaklaşım gibi görünüyor.

Yapabilirsin JS Fiddle'da kontrol et

<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/JSXTransformer.js"></script>
<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/react-with-addons.js"></script>

<script type="text/jsx">
/** @jsx React.DOM */
    
var If = React.createClass({
  displayName: 'If',

  render: function()
  {
    if (this.props.condition)
      return <span>{this.props.children}</span>
    return null;
  }
});

var Main = React.createClass({
    render: function() {
        return (
           <div>
             <If condition={false}>
                <div>Never showing false item</div>
             </If>
             <If condition={true}>
                <div>Showing true item</div>
             </If>
          </div>
        );
    }
});

React.renderComponent(<Main/>, document.body);
</script>

Yukarıdaki sonuçları çalıştırmak:

Gerçek öğe gösteriliyor


44
2017-08-10 01:47


Menşei


olası kopyası Koşullu öğelere nasıl sahip olunur ve Facebook'taki KURUMSAL JSX ile nasıl davranılır? - FakeRainBrigand
Bu, insanlara React ile başladığı zaman zaman istenir, ancak birkaç hafta boyunca kullanıldıktan sonra bunu istemeyi bıraktılar. Sadece üçlü veya && Şartı diğer soruda belirtildiği gibi işler hale getirmek. - FakeRainBrigand
Hey! Geri bildiriminiz için teşekkürler .... Koşullu olarak bir değişkene yansıtma yaklaşımını kullanıyorum ve sonra bu değişkeni benim render yanıt ve iyi çalışıyor. Bu yaklaşıma sahip olan şey, JSX'i kırması ve yanıtlarımda HTML'nin tüm yapısını görmeyi zorlaştırmasıdır. Bu yüzden belki bir düşündüm If Bileşen bu durumlarda yardımcı olabilir ve bir yanıtın tam olarak işaretlenmesi bu koşullarda görmenin daha kolay olmasını sağlar - ancak üçlü yaklaşımı / satır içi koşullarını hiç fark etmedim ve muhtemelen bunlardan birini kullanacağım. - Brad Parks
Evet, mantığı anlıyorum. İlk başta aynı şeyi düşündüm. - btw, kapalı sorular genellikle google'da çok fazla trafik alır, ancak evet, başka bir soru varsa, bu soruya işaret etmek için kapatılmalıdır. - FakeRainBrigand
Geri dönmek yerine <noscript/>, iade etmeyi tercih et null React 0.11'den beri mümkündür. - Sophie Alpert


Cevaplar:


Kontrol et JSX'te Else tepkisi bölümündeki dokümanlar.

JSX'te, kaşlı ayraçlar içine ifadeler koyamazsınız - yalnızca ifadeler. JavaScript'teki ifadeler ve ifadeler arasındaki farkı bilmiyorsanız bunu okuyun makale. Bu sınırlama, JSX desugars'ın işlev çağrılarına girmesi ve JavaScript'teki bir işlevin argümanları olarak if ifadeleri kullanamazsınız. Ancak, boole işleçlerini kullanabilirsiniz (&&, || ve ? :) benzer bir iş yapmak. Bunlar, JSX'in oluşturduğu yapıcıların içine sığabilecekleri ifadelerdir ve kısa devre değerlendirmeleri, ifadelerde kullanıldıkları ile aynıdır.

<div>
    {(true
        ? <div>Showing true item</div>     
        : <div>Never showing false item</div>
    )}
</div>
<p>My name is {this.name || "default name"}</p>

Ayrıca, React tedavi edecek null ve false gerçek DOM'de işlenmeyen bir "boş bileşen" olarak (şu anda sahnelerin arkasında aynı noscript hilesi kullanır). Bu, "başka" bir şube istemediğinizde yararlıdır. Görmek JSX içinde yanlış detaylar için.

<div>
    {shouldIncludeChild ? <ChildComponent/> : false}
</div>

Sorduğunuz bileşenle ilgili olarak, sahip olduğu bir problem şu anki haliyle, koşul yanlış olsa bile çocuklarını değerlendirecektir. Bu durum, eğer koşul doğruysa sadece If komutunu verirse hatalara yol açabilir:

<If condition={person !== null}>
    //This code throws an exception if this.person is null
    <div>{person.name}</div>
</If>

Bunu, eğer bileşen, vücudu alt bileşenlerin bir listesi yerine bir işlev olarak alıyorsa, ancak daha ayrıntılı bir çözümle bu sorunu çözebilirsiniz:

<If condition={person !== null} body={function(){
    return <div>{person.name}</div>
}/>

Son olarak, eğer Bileşen vatansızsa, yeni bir bileşen sınıfı yerine düz bir işlev kullanmayı düşünmelisiniz, çünkü bu, “If” ı React'ın mutabakat algoritmasına şeffaf hale getirecektir. Eğer bir If bileşeni kullanırsanız, o zaman <div> ve bir <If><div> Uyumsuz olarak kabul edilecek ve React, yeni bileşeni eski ile birleştirmeye çalışmak yerine tam bir yeniden çizim yapacak.

// This custom if function is for purely illustrative purposes
// However, this idea of using callbacks to represent block of code
// is useful for defining your own control flow operators in other circumstances.
function myCustomIf(condition, onTrue, onFalse){
    onTrue  = onTrue  || function(){ return null }        
    onFalse = onFalse || function(){ return null }
    if(condition){
        return onTrue();
    }else{
        return onFalse();
    }
}

<div>    
    {myCustomIf(person !== null, function(){
         return <div>{person.name}</div>
     })}
</div>

56
2017-08-10 02:38



Bunu ES2015 ile yapabilirsiniz: gist.github.com/Ginhing/58305312a75f7f6d6165bb583ecc94ba - Ginhing
"Şişman ok" işlevinin sözdizimi, myCustomIf'in kullanımını daha kolay hale getirir, ancak yerleşik olanı kullanmayı tercih ederim. ?: yerine. - hugomg
Bu yine de soruyu yanıtlıyor. - Petr Peller
Fakat eğer redux kullanıyorsanız, ana bileşeninizi bağlandığınızda kontrol ettiğiniz durumdan haberdar olmamanızı sağlayabilirsiniz. Yani kapsayıcı AppWasLoaded temel oluşturabilir. condition özelliği. Böyle bir durumda, daha spesifik kaplar oluşturmak için kullanmak ve kullanmak iyi bir fikir olmaz mıydı? - panurg


Basit bir JS'den başka bir şeye ihtiyacınız yok.

Güvenli ve okunabilir (ancak ayrıntılı)

maybeRenderPerson: function() {
    var personName = ...;
    if ( personName ) {
        return <div className="person">{personName}</div>;
    }
}

render: function() {
    return (
       <div className="component">
          {this.maybeRenderPerson()}
       </div>
    );
}

Bu biraz ayrıntılı, ancak mantığınızı daha küçük, odaklanmış bloklarda kolayca bölmenize izin veriyor. Bileşenler karmaşıklaşmaya başladığında, bu en okunaklı olanıdır.


Özlü ve okunabilir (ama tehlikeli)

render: function() {
    var personName = ...; // present or absent name, but never ""
    return (
       <div className="component">
          {personName && (
            <div className="person">{personName}</div>
          )}
       </div>
    );
}

Test edilen değişken falsi değerler gibi olabilirse bu sözdizimi oldukça tehlikeli olabilir. 0,"" veya false. Özellikle rakamlarla, 0 için oluşturduğundan emin olmak istiyorsanız testi biraz değiştirmelisiniz:

render: function() {
    var counter= ...; // number, can be 0
    return (
       <div className="component">
          {(typeof counter !== 'undefined') && (
            <div className="counter">{counter}</div>
          )}
       </div>
    );
}

Bileşenler karmaşık hale geldiğinde, birden çok küçük bileşene bölünür ve kod stili kuralları olması okunabilir durumda tutmaya yardımcı olabilir:

render: function() {
    var person= ...; 
    var counter= ...; 
    return (
       <div className="component">
          {person && (
            <Person person={person}/>
          )}
          {(typeof counter !== 'undefined') && (
            <Counter value={counter}/>
          )}
       </div>
    );
}

Modern sözdizimi (ama çok erken)

do Fonksiyonel durum bilgisi olmayan bileşenlere sahip notasyon okunabilirliği kaybetmeksizin ifade için yararlı olabilir. Büyük bir bileşeni kolayca kullanan çok küçük ve odaklanmış olanlara bölebilirsiniz. do notasyonu:

const Users = ({users}) => (
  <div>
    {users.map(user =>
      <User key={user.id} user={user}/>
    )}
  </div>
)  

const UserList = ({users}) => do {
  if (!users) <div>Loading</div>
  else if (!users.length) <div>Empty</div>
  else <Users users={users}/>
}

JSX'in içindeki modül modelini kullanmak biraz gibidir, bu yüzden oldukça esnektir, ancak daha az boilerplate ile.

Bunu etkinleştirmek için ES7 aşama 0 derleme aracına ihtiyacınız vardır ve favori IDE'nizden destek henüz mevcut olmayabilir.


33
2017-08-10 13:02



Şimdiye kadar okudum en doğru cevap, çünkü süper deyimsel. İyi fikir. - sospedra
Bu kesinlikle güzel ve temiz olduğunu kabul ediyorum ... Ve daha fazla fonksiyon ekleyerek okunabilirliği artırabilir ve yığın yığınlama ve damping de yardımcı olabilir! - Brad Parks
Bu yolla, en basit koşullu kontrol için ideal olan bir yol buldum ve birçok farklı React bileşeni arasında seçim yaparken (yani bir anahtar deyimini uygularken) harikadır. - gbmhunter
Bu ES7 örneği gerçekten harika! Aynı modeli ES6 ile kaldırarak do üç ekleyerek return ifadeleri. - styfle


Bu gibi satır içi koşullarını yapabilirsiniz

{true && (
<div>render item</div>
)}

{false && (
<div>don't render item</div>
)}

Ya da sadece bir var

var something;

if (true) {
something = <div>render item</div>
}

{something}

14
2017-08-10 02:49





Doğru bağlamda (Babel yardımıyla) kendi kendini idare eden bir işlev de yapabilirsiniz! Tercih ettiğim, değişkenlerin atanmasına gerek olmadığı ve istediğiniz kadar karmaşık olabileceğinizden (muhtemelen bakım için yapmamalısınız):

render() {
  return (
    <div>
      <div>Hello!</div>
      {() => {
        if (this.props.isLoggedIn) {
          return <Dashboard />
        } else {
          return <SignIn />
        }
      }()}
      <div>Another Tag</div>
    </div>
  );
}

4
2017-07-20 15:48





Deneysel ES7 do sözdizimi bu durum için gerçekten güzel. Babel kullanıyorsanız, es7.doExpressions özellik o zaman:

render() {
  var condition = false;

  return (
    <div>
      {do {
        if (condition) {
          <span>Truthy!</span>;
        } else {
          <span>Not truthy.</span>;
        }
      }}
    </div>
  );
}

Görmek http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions


3
2017-07-11 02:57





ES7 do kapatma bunun için harika:

Örneğin, kullanıyorsanız webpack - ES7 özelliklerini ekleyebilirsiniz:

Öncelikle yükleyin stage-0 ile özellikleri:

npm install babel-preset-stage-0 -save-dev;

Daha sonra webpack yükleyici ayarlarında stage-0 babel preset'i ekleyin:

    loaders : [
        //...
        {
            test : /\.js$/,
            loader : "babel-loader",
            exclude : /node_modules/,
            query : {
                presets : ["react", "stage-0", "es2015"]
            }
        }
    ]

Daha sonra bileşen render işleviniz şöyle görünebilir:

import React , { Component } from "react";

class ComponentWithIfs extends Component {

    render() {
        return (
            <div className="my-element">
                {
                    do {
                        if ( this.state.something ) {
                            <div>First Case</div>
                        } else {
                            <div>2nd Case</div>
                        }
                    }
                }
            </div>
        );
    }
}

1
2018-05-10 12:51





Bence asıl soru "Ben bir Eğer bileşeni (çünkü açıkça yapabilirsiniz), ama "neden bir neden uygulamak için herhangi bir sebep var mı Eğer bileşen kötü bir fikir mi? "

Kötü bir fikir olmasının ana sebebi, bir bileşenin, var olan bir bileşendeki küçük bir miktar kodun ne olacağına bir döngü oluşturmasıdır. Ekstra bileşenli sarıcı, React'ın çocuklarında ekstra render döngüsünün tamamını çalıştırması gerektiği anlamına gelir. Eğer bu büyük bir şey değil Eğer bileşen yalnızca tek bir yerde kullanılır, ancak uygulamanız bunlarla doluysa, UI'nizi çok daha yavaş bir hale getirdiniz.

Nasıl benzer: <div>Hi</div> daha verimli <div><div>Hi</div></div>.


1
2018-02-21 23:09



mükemmel cevap. dinlenme tüm tepki becerilerini gösteriyor - hannad rehman


Sürdürülebilir kod için, gereksiz soyutlamaları atlayın If ve bir kontrol mantığını erken sonlandırma önce return senin deyiminde render yöntem, ör.

import React from 'react-native';

let {
  Text
} = React;

let Main = React.createClass({
  setInitialState() {
    return { isShown: false }
  },
  render() {
    let content;
    if (this.state.isShown) {
      content = 'Showing true item'
    } else {
      return false;
    }
    return (
      <Text>{content}</Text>
    );
  }
});

Seni korur. Kalıcı koruma.


0
2018-05-16 18:10





Eğer ilgilenen varsa, tepki modülü bu amaçlar için:

var Node = require('react-if-comp');
...
React.createClass({
    render: function() {
        return (
            <div>
                <Node if={false} else={<div>Never showing false item</div>} />
                <Node if={true} then={<div>Showing true item</div>} />
            </div>
        );
    }
});

0
2018-01-08 23:04





işlemek -eğer bir koşul tatmin edildiyse, bir eleman oluşturacak hafif bir işlevdir

Bir satır içi ifade olarak

class MyComponent extends Component {
  render() {
    return (
      {renderIf(1 + 2 === 3)(
        <span>The universe is working</span>
      )}
    );
  }
}

İsimlendirilmiş bir işlev olarak

class MyComponent extends Component {
  render() {
    const ifTheUniverseIsWorking = renderIf(1 + 2 === 3);
    return (
      {ifTheUniverseIsWorking(
        <span>The universe is still wroking</span>
      )}
    )
  }
}

Oluşan bir işlev olarak

const ifEven = number => renderIf(number % 2 === 0);
const ifOdd = number => renderIf(number % 2 !== 0);

class MyComponent extends Component {
  render() {
    return (
      {ifEven(this.props.count)(
        <span>{this.props.count} is even</span>
      )}
      {ifOdd(this.props.count)(
        <span>{this.props.count} is odd</span>
      )}
    );
  }
}

0
2018-02-05 07:01





Benim için başka bir ifade gerekmiyorsa, mantıksal ifadede tembel değerlendirmeden yararlanmak için yeterlidir:

render() {
    return(
        <div>
             {
                 condition &&
                     <span>Displayed if condition is true</span>
             }
        </div>
    );    
}

Veya başka bir şeye ihtiyaç varsa ternay operatörü:

render() {
    return(
        <div>
             {
                 condition ?
                     <span>Displayed if condition is true</span>
                          :
                     <span>Displayed if condition is false</span>
             }
        </div>
    );    
}

0
2017-09-29 15:14