Reactコンポーネントに属性を条件付きで追加するにはどうすればよいですか?


551

特定の条件が満たされた場合にのみReactコンポーネントに属性を追加する方法はありますか?

レンダリング後のAjax呼び出しに基づいてフォーム要素にrequired属性とreadOnly属性を追加することになっていますが、readOnly = "false"は属性を完全に省略するのと同じではないため、これを解決する方法を理解できません。

以下の例は、私が何を望んでいるかを説明しているはずですが、機能しません(解析エラー:予期しない識別子)。

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
1つのコメントが誰かを助けるかもしれませんが、ストアでそれらのみを変更し(fe redux)、コンポーネントに関連付けられている場合、React 16.7 がコンポーネントのhtml属性を再レンダリングおよび更新しないことがわかりました。つまり、コンポーネントにはfeがありaria-modal=true、変更を(falseに)aria / data属性のストアにプッシュしますが、結果のReactJはaria /を更新しないため、他の何も変更されません(コンポーネントのコンテンツ、クラスまたは変数など)。 そのコンポーネントのデータ属性。私はそれを実現するために一日中ぐるぐる回っています。
AlexNikonov

回答:


535

明らかに、特定の属性については、Reactは、渡した値が真実でない場合、属性を省略できるほどインテリジェントです。例えば:

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

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

結果は:

<input type="text" required>

アップデート:誰もが、これはなぜ起こるか、あなたが特にラインで、ReactDOMのソースコードで詳細を見つけることができますどのように/へと好奇心旺盛であれば30167DOMProperty.jsのファイル。


45
通常null、「まったく指定しなかったように振る舞う」という意味です。boolean dom属性の場合、true / falseは属性name / falseを繰り返すよりも優先されます。たとえば、<input disabled>コンパイルはReact.createElement('input', {disabled: true})
Brigand

同意する。以前は特定のブラウザーで問題があり、習慣があまりにも多く、手作業で="required"パーツを追加したため、この名前を繰り返します。Chromeは実際には値なしで属性のみをレンダリングしました。
juandemarco

8
readonlyReactが属性readOnly(大文字のO)を期待しているため、追加されません。
最大

8
ありがとう!値が空の文字列やゼロでないことを確認してください。これらは削除されない場合があります。たとえば、次のような値を渡すことができ、falseと評価された場合は削除されることを確認する必要がありますalt={props.alt || null}
Jake

5
ありがとう、@ Jake。属性をfalseに設定しようとnullしましたが、属性が実際に削除されたことを確認しただけです。
Nathan Arthur

386

フアンデマルコの答えは通常正しいですが、ここに別の選択肢があります。

好きなようにオブジェクトを作成します。

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

if (condition)
  inputProps.disabled = true;

必要に応じて他の小道具も渡し、スプレッドでレンダリングします。

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

14
これは実際に、特に条件付きで多くのプロパティを追加する場合に非常に便利です(そして、私は個人的にそれがこのようにできることを知りませんでした)。
juandemarco 2015

1
非常にエレガントですが、inputProps.disabled = trueにすべきではありませんか?
Joppe

非常に単純です。複数の条件を指定せずにコードを読みやすくしました。
Naveen Kumar PG

これの正確な意味について誰も苦労した場合、「砂糖、」あなたは関数があることがわかりますにあなたの.jsxのがtranspiledされていることをスクリプトで見ることができます_extends(通常の状況下で)取るであろう、それに追加されているpropsから構築を「通常の属性」を適用しますObject.assign(props, inputProps)
Nathan Chappell、

299

以下は、React-Bootstrap(バージョン0.32.4)を介したBootstrapの使用例です。Button

var condition = true;

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

状態により、{bsStyle: 'success'}またはどちらか{}が返却されます。その後、spreadオペレーターは、返されたオブジェクトのプロパティをButtonコンポーネントに拡散します。偽の場合、返されるオブジェクトにはプロパティが存在しないため、コンポーネントには何も渡されません。


Andy Polhillのコメントに基づく別の方法:

var condition = true;

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

唯一の小さな違いは、2番目の例では、内部コンポーネント<Button/>propsオブジェクトにbsStyleの値を持つキーがあることですundefined


5
@ Punit、spread演算子は条件演算子よりも優先順位が低いため、最初に条件が評価され(そのいずれか{bsStyle: 'success'}または{}その結果)、次にオブジェクトが展開されます。
Victor Zamanian 2017年

5
以下は同じ<Button bsStyle={ condition ? 'success': undefined } /> ことを行いますが、構文が少し簡単であると 思いますundefined。渡すとプロパティが省略されます。
Andy Polhill、2018年

3
@AndyPolhillは私にとって見栄えがよく、コードをはるかに読みやすくなっています。唯一の小さな違いは、コード例では内部コンポーネント<Button/>propsオブジェクトにのbsStyle値を持つキーがあることですundefined
アルマンYeghiazaryan

@AndyPolhill構文が読みにくいと思われる理由は、暗黙的な括弧が欠けているために、例が外国語に見えて理解しにくいためです。例を編集して括弧を追加します。
Govind Rai

1
最初の方法は私にとって完璧に機能しました。ありがとう
Liran H

86

これが代替案です。

var condition = true;

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

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

またはそのインラインバージョン

var condition = true;

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

9
私はこのアプローチが好きで、同僚の間でクールになります。冗談はさておき、その外観からすると、結局のところ、小道具はキーと値のペアとして渡されるだけですが、それは正しいですか。
JohnnyQ 2017年

1
conditionがfalseの場合、これはfalseを拡張または反復しようとしますが、これは正しくないと思います。
LarsNyström2017

1
@LarsNyström、それは理にかなっています。スプレッド演算子は、false1 でない反復可能オブジェクトのみを受け入れます。Babelで確認してください。これは、conditionBabelが演算子を実装する方法からfalseと評価された場合に機能します。ささいな回避策は可能性がありますが...( condition ? { disabled: true } : {} )、それは少し冗長になります。この素晴らしい入力をありがとう!
シーズン

+1条件付きで出力したい場合data-*aria-*属性がJSXの特殊なケースであるため、このアプローチは必須であり、属性を省略せずdata-my-conditional-attr={ false }に出力data-my-conditional-attr="false"します。facebook.github.io/react/docs/dom-elements.html
ptim

32

これが私のやり方です。

条件付き

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

私はまだ小道具を渡す通常の方法を使用することを好みます。条件付きがない場合は(私の意見では)より読みやすいからです。

条件なし

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

この部分がどのように機能するか説明していただけますか...(tooltip && { tooltip }),?これはコンポーネントで機能しますが、コードでこのようなものを使用しようとすると、エラーが発生し、反復不可能な値を拡散しようとします
skwisgaar

おそらくfalseyValue && {}falseが返されるため、falseなどで拡散している可能性があります...(false)。完全な表現を使用する方がはるかに良いため、スプレッドは引き続き動作します ...(condition ? {foo: 'bar'} : {})
lfender6445

19

コンポーネント(の一部)の追加/削除に使用するのと同じショートカットを使用できます({isVisible && <SomeComponent />})。

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

3
もしsomeCondition本当であるが、someValue(例えばfalsyであるfalse自分自身を、または0、など)、属性がまだ含まれますでしょうか?明示的にfalsy値、例えばAを含める必要がある場合、これは重要である0座標属性のためなど、
アンドリュー・ウィレムス

通常、属性は省略されますが、data-*and の場合は除外されませんaria-*。上記の私のコメントを参照してください。値を引用するか、文字列としてキャストすると、属性が表示されます。例:someAttr={ `${falsyValue}` }レンダリング可能someAttr="false"
ptim

19

条件がtrueの場合、カスタムプロパティ(aria- *またはdata- *を使用)を追加するとします。

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

条件が真の場合にスタイルプロパティを追加するとします。

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

10

ECMAScript 6を使用する場合は、次のように書くだけです。

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

6

Ajax呼び出し後に状態が変化し、親コンポーネントが再レンダリングされるため、これは機能するはずです。

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

3

Reactでは、条件付きでコンポーネントをレンダリングできますが、props、className、idなどの属性もレンダリングできます。

Reactでは、3項演算子を使用することをお勧めします条件付きでコンポーネントをレンダリングするのに役立つことをお勧めします。

例では、コンポーネントとそのスタイル属性を条件付きでレンダリングする方法も示しています。

以下に簡単な例を示します。

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>


これは、多くの属性を使用すると、非常に複雑になる可能性があります。スプレッドバリアントの方が好きです。
Remi Sture

はいあなたは正しいですが、これは概要を知る必要がある人のためのものです私は別の例を作ります。しかし、物事をシンプルに保ちたい。
ジュラジ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.