React bileşenlerine koşullu olarak özellikleri nasıl eklerim?


551

React bileşenine yalnızca belirli bir koşul karşılandığında özellikler eklemenin bir yolu var mı?

Oluşturduktan sonra bir Ajax çağrısı dayalı form öğelerine gerekli ve readOnly öznitelikleri eklemek gerekiyordu, ancak readOnly = "false" özniteliği tamamen atlamak aynı değildir çünkü bu nasıl çözülemiyor.

Aşağıdaki örnek ne istediğimi açıklamalı, ancak çalışmaz (Ayrıştırma Hatası: Beklenmeyen tanımlayıcı).

var React = require('React');

var MyOwnInput = React.createClass({
    render: function () {
        return (
            <div>
                <input type="text" onChange={this.changeValue} value={this.getValue()} name={this.props.name}/>
            </div>
        );
    }
});

module.exports = React.createClass({
    getInitialState: function () {
        return {
            isRequired: false
        }
    },
    componentDidMount: function () {
        this.setState({
            isRequired: true
        });
    },
    render: function () {
        var isRequired = this.state.isRequired;

        return (
            <MyOwnInput name="test" {isRequired ? "required" : ""} />
        );
    }
});

1
Birisi yardım biri olabilir, ben React 16.7 yeniden ortaya çıkarmaz ve sadece bir mağaza (fe redux) onları değiştirdiyseniz ve bileşene bağlıysa bileşenin html özniteliklerini güncellemediğini öğrendim . Bu, bileşenin fe'ya sahip olduğu anlamına gelir, aria-modal=truedeğişiklikleri aria / veri öznitelikleri deposuna itersiniz, ancak sonuç ReactJ'ler aria /' yı güncellemeyeceğinden başka hiçbir şey değiştirilmez (bileşenin içeriği veya sınıfı veya değişkenleri gibi). bu bileşenlerde veri yıpranması. Bunu anlamak için bütün gün uğraşıyordum.
AlexNikonov

Yanıtlar:


535

Görünüşe göre, belirli özellikler için React, geçtiğiniz değer doğru değilse özelliği atlayacak kadar zekidir. Örneğin:

var InputComponent = React.createClass({
    render: function() {
        var required = true;
        var disabled = false;

        return (
            <input type="text" disabled={disabled} required={required} />
        );
    }
});

sonuçlanacak:

<input type="text" required>

Güncelleme: Herkes, özellikle hatları, bu durumda, neden ReactDOM kaynak kodunda ayrıntıları bulabilirsiniz nasıl / geldiğini merak ediyor ise 30 ve 167 arasında DOMProperty.js dosyası.


45
Genel olarak null"hiç belirtmediğim gibi davran " anlamına gelir. Boole dom öznitelikleri için true / false, name / false özniteliğinin yinelenmesine göre tercih edilir, örn <input disabled>.React.createElement('input', {disabled: true})
Brigand

Katılıyorum. Adı tekrar ediyorum çünkü geçmişte bazı tarayıcılarda sorun yaşadım ve alışkanlık bana o kadar yapıştı ki, ="required"parçayı manuel olarak ekledim . Chrome aslında değeri olmayan yalnızca niteliği oluşturdu.
juandemarco

8
readonlyAsla eklenmez çünkü React bu özelliği bekler readOnly(büyük O harfi ile).
Maksimum

8
Teşekkürler! Değerin yalnızca boş bir dize veya sıfır olmadığından emin olun, bunlar kaldırılamayabilir. Örneğin, böyle bir değeri geçebileceği ve bunun yanlış değerlendirilirse emin kaldırılır yapmalıdır: alt={props.alt || null}.
Jake

5
Teşekkürler @ Jake. Özniteliği ayarlamayı denedim false, ancak yalnızca nullözniteliğin gerçekten kaldırıldığından emin oldum .
Nathan Arthur

386

juandemarco'nun cevabı genellikle doğrudur, ancak işte başka bir seçenek.

Nasıl bir nesne oluşturun:

var inputProps = {
  value: 'foo',
  onChange: this.handleChange
};

if (condition)
  inputProps.disabled = true;

İsteğe bağlı olarak diğer desteklerden geçerek yayılmış hale getirin.

<input
    value="this is overridden by inputProps"
    {...inputProps}
    onChange={overridesInputProps}
 />

14
Bu, özellikle şartlı olarak birçok özellik eklerken çok yararlıdır (ve şahsen bu şekilde yapılabileceğine dair hiçbir fikrim yoktu).
juandemarco

1
Çok zarif, ancak inputProps.disabled = true olmamalı mı?
Joppe

çok basit, kodumu daha birden fazla koşullara sahip daha okunabilir hale getirdik.
Naveen Kumar PG

Herkes bu "şekerin" kesin anlambilimine önem verirse, .jsx'inizin aktarıldığı komut dosyasına bakabilirsiniz _extends(normal şartlar altında) propsyapıyı "normal nitelikler" ve uygulayın Object.assign(props, inputProps).
Nathan Chappell

299

Burada kullanan bir örnek , özyükleme sitesindeki Buttonile React-Bootstrap (sürüm 0.32.4):

var condition = true;

return (
  <Button {...(condition ? {bsStyle: 'success'} : {})} />
);

Durumuna bağlı olarak, ya {bsStyle: 'success'}ya {}iade edilir. Forma operatörü daha sonra döndürülen nesnenin özelliklerini Buttonbileşene yayar . Falsy durumunda, döndürülen nesne üzerinde hiçbir özellik olmadığından, bileşene hiçbir şey iletilmez.


Andy Polhill'in yorumuna dayanan alternatif bir yol :

var condition = true;

return (
  <Button bsStyle={condition ? 'success' : undefined} />
);

Sadece küçük fark, ikinci örnekte iç bileşen olmasıdır <Button/>'in propsamacı, bir anahtar olacak bsStylebir değer ile undefined.


5
@Punit, Forma operatörünün koşullu işleçten daha düşük bir önceliği vardır, bu nedenle önce koşul değerlendirilir (ya {bsStyle: 'success'}da {}ondan sonuçlanır), sonra bu nesne yayılır.
Victor Zamanian

5
Aşağıdaki aynı <Button bsStyle={ condition ? 'success': undefined } /> sözdizimi biraz daha kolay bulur undefinedmuydunuz , geçen özelliği atlayacak.
Andy Polhill

3
@AndyPolhill bana iyi ve kodu çok daha kolay okunur görünüyor sadece küçük fark, kod örneğinde iç bileşeni olmasıdır <Button/>'ın propsnesne bir anahtarı olacaktır bsStyledeğeriyle undefined.
Arman Yeghiazaryan

@AndyPolhill sözdiziminin okunmasının daha zor görünmesinin nedeni, örneğin yabancı görünmesini ve anlaşılmasını zorlaştıran bazı örtülü parantezlerin eksik olmasıdır. Parantez eklemek için örneği düzenleme.
Govind Rai

1
İlk yöntem benim için mükemmel çalıştı, teşekkür ederim
Liran H

86

İşte bir alternatif.

var condition = true;

var props = {
  value: 'foo',
  ...( condition && { disabled: true } )
};

var component = <div { ...props } />;

Veya satır içi sürümü

var condition = true;

var component = (
  <div
    value="foo"
    { ...( condition && { disabled: true } ) } />
);

9
Bu yaklaşımı seviyorum, iş arkadaşlarım arasında beni serinletiyor. Şaka bir yana, görünüşe göre, aksesuarlar sadece bir anahtar-değer çifti olarak geçiyorlar, doğru mu?
JohnnyQ

1
Eğer conditionyanlışsa, yanlış olduğunu düşünmeye çalışacağım.
Lars Nyström

1
@ LarsNyström, Bu mantıklı. Forma operatörü yalnızca bir değil tekrarlanabilirleri kabul eder false. Babel ile kontrol et. Bu condition, Babel'in operatörü uygulama şekli nedeniyle yanlış olarak değerlendirildiğinde onunla çalışır . Önemsiz bir çözüm olsa da ...( condition ? { disabled: true } : {} ), o zaman biraz ayrıntılı olur. Bu güzel girdi için teşekkürler!
Sezon

+1 Bu yaklaşım, JSX'te özel bir durum oldukları için koşullu çıktı data-*veya aria-*öznitelikler istiyorsanız, özniteliği atlamak yerine data-my-conditional-attr={ false }çıktı alacaktır data-my-conditional-attr="false". facebook.github.io/react/docs/dom-elements.html
ptim

32

İşte bunu yapmanın bir yolu.

Bir şartla :

<Label
    {...{
      text: label,
      type,
      ...(tooltip && { tooltip }),
      isRequired: required
    }}
/>

Ben hala sahne geçerek düzenli bir şekilde kullanmayı tercih ediyorum, çünkü herhangi bir koşul olmaması durumunda daha okunabilir (bence).

Koşulsuz :

<Label text={label} type={type} tooltip={tooltip} isRequired={required} />

Lütfen bu bölümün nasıl çalıştığını açıklayabilir misiniz ...(tooltip && { tooltip }),? Bileşen üzerinde çalışır ama kodda böyle bir şey kullanmaya çalıştığınızda ben yinelemeyen değeri yaymaya çalışacağım anlamına gelen bir hata alıyorum
skwisgaar

muhtemelen falseyValue && {}yanlış dönecektir, bu yüzden muhtemelen yanlış yayılıyor örneğin ...(false). tam ifade kullanmak çok daha iyi yayıldı davranmaya devam ediyor ...(condition ? {foo: 'bar'} : {})
lfender6445

19

Bileşenleri ( {isVisible && <SomeComponent />}) eklemek / kaldırmak için kullanılan kısayolu kullanabilirsiniz .

class MyComponent extends React.Component {
  render() {
    return (
      <div someAttribute={someCondition && someValue} />
    );
  }
}

3
Eğer someConditiondoğruysa ama someValuefalsy olduğu (örneğin falsekendisi veya 0, nitelik hala eklenmiş olsun demek, vb)? Açıkça bir bir falsy değeri, örneğin dahil etmek gerekirse, bu önemlidir 0vb bir koordinat özelliği için
Andrew Willems

Normalde, nitelik, ancak söz konusu atlanırsa data-*ve aria-*yukarıdaki yorumumu görüyoruz. Değeri teklif ederseniz veya bir String olarak someAttr={ `${falsyValue}` }someAttr="false"
yayınlarsanız

19

Koşul doğru olduğunda özel bir özellik (aria- * veya data- * kullanarak) eklemek istediğimizi varsayalım:

{...this.props.isTrue && {'aria-name' : 'something here'}}

Bir koşul doğruysa bir stil özelliği eklemek istediğimizi varsayalım:

{...this.props.isTrue && {style : {color: 'red'}}}

10

ECMAScript 6 kullanıyorsanız, böyle yazabilirsiniz.

// First, create a wrap object.
const wrap = {
    [variableName]: true
}
// Then, use it
<SomeComponent {...{wrap}} />

7

Ajax çağrısından sonra durumunuz değişeceğinden ve üst bileşen yeniden oluşturulacağından, bu çalışmalıdır.

render : function () {
    var item;
    if (this.state.isRequired) {
        item = <MyOwnInput attribute={'whatever'} />
    } else {
        item = <MyOwnInput />
    }
    return (
        <div>
            {item}
        </div>
    );
}

3

React'te koşullu olarak Bileşenler'i, ancak aynı zamanda props, className, id ve diğerleri gibi niteliklerini oluşturabilirsiniz.

React'te, koşullu olarak Bileşenler oluşturmanıza yardımcı olabilecek üçlü operatörü kullanmak çok iyi bir uygulamadır .

Bir örnek ayrıca, Bileşenin ve stil özelliğinin koşullu olarak nasıl oluşturulacağını gösterir.

İşte basit bir örnek:

class App extends React.Component {
  state = {
    isTrue: true
  };

  render() {
    return (
      <div>
        {this.state.isTrue ? (
          <button style={{ color: this.state.isTrue ? "red" : "blue" }}>
            I am rendered if TRUE
          </button>
        ) : (
          <button>I am rendered if FALSE</button>
        )}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>


Bu, birçok özellik ile gerçekten dağınık olabilir. Forma varyantını daha çok seviyorum.
Remi Sture

Evet Haklısın ama bu genel bakış almak isteyen biri için başka bir örnek vereceğim. Ama işleri basit tutmak istiyorum.
Juraj

0

JSX yazısını dikkate alarak, sorununuzu şu şekilde çözebilirsiniz:

if (isRequired) {
  return (
    <MyOwnInput name="test" required='required' />
  );
}
return (
    <MyOwnInput name="test" />
);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.