Existe-t-il un moyen d’ajouter des attributs à un composant React si une certaine condition est remplie?
Je suis supposé ajouter les attributs required et readOnly aux éléments de formulaire basés sur un appel ajax après le rendu, mais je ne vois pas comment résoudre ce problème car readOnly = "false" ne revient pas à omettre complètement l'attribut.
L'exemple ci-dessous devrait expliquer ce que je veux, mais ne fonctionnera pas (Erreur d'analyse: identifiant inattendu).
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" : ""} />
);
}
});
Apparemment, pour certains attributs, React est suffisamment intelligent pour omettre cet attribut si la valeur que vous lui transmettez n'est pas véridique. Par exemple:
var InputComponent = React.createClass({
render: function() {
var required = true;
var disabled = false;
return (
<input type="text" disabled={disabled} required={required} />
);
}
});
aura pour résultat:
<input type="text" required data-reactid=".0.0">
Il suffit de jeter une autre option, mais la réponse de @ juandemarco est généralement correcte.
Construisez un objet comme vous le souhaitez:
var inputProps = {
value: 'foo',
onChange: this.handleChange
};
if (condition) inputProps.disabled = true;
Render avec spread, en passant éventuellement d'autres accessoires également.
<input
value="this is overridden by inputProps"
{...inputProps}
onChange={overridesInputProps}
/>
Voici un exemple d'utilisation de Bootstrap Button
via React-Bootstrap (version: 0.32.4).
var condition = true;
return (
<Button {...(condition ? {bsStyle: 'success'} : {})} />
);
En fonction de la condition, {bsStyle: 'success'}
ou {}
sera renvoyé. L'opérateur de propagation répandra ensuite les propriétés de l'objet renvoyé au composant Button
. Dans le cas de falsy, étant donné qu'aucune propriété n'existe sur l'objet renvoyé, rien ne sera transmis au composant.
Une autre manière basée sur le commentaire de @Andy Polhill ci-dessous:
var condition = true;
return (
<Button bsStyle={condition ? 'success' : undefined} />
);
La seule petite différence est que, dans le 2ème exemple de composant interne, l'objet props
de <Button/>
aura une clé bsStyle
avec la valeur undefined
.
En retard à la fête. Voici une alternative.
var condition = true;
var props = {
value: 'foo',
...( condition && { disabled: true } )
};
var component = <div { ...props } />;
Ou sa version en ligne
var condition = true;
var component = (
<div
value="foo"
{ ...( condition && { disabled: true } ) } />
);
Voici une façon dont je le fais.
avec conditionnel:
<Label
{...{
text: label,
type,
...(tooltip && { tooltip }),
isRequired: required
}}
/>
Je préfère toujours utiliser la méthode habituelle de transmission des accessoires, car elle est plus lisible (à mon avis) dans le cas de ne pas avoir de conditionnel.
avec sans condition:
<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
Vous pouvez utiliser le même raccourci, utilisé pour ajouter/supprimer des composants ({isVisible && <SomeComponent />}
).
class MyComponent extends React.Component {
render() {
return (
<div someAttribute={someCondition && someValue} />
);
}
}
En retard à la fête.
Disons que nous voulons ajouter une propriété personnalisée (en utilisant aria- * ou data- *) si une condition est vraie:
{...this.props.isTrue && {'aria-name' : 'something here'}}
Disons que nous voulons ajouter une propriété de style si une condition est vraie:
{...this.props.isTrue && {style : {color: 'red'}}}
Si vous utilisez es6, vous pouvez simplement écrire comme ceci.
// first, create a wrap object.
const wrap = {
[variableName]: true
}
// then, use it
<SomeComponent {...{wrap}} />
Cela devrait fonctionner, car votre état changera après l'appel ajax et le composant parent sera rendu de nouveau.
render : function () {
var item;
if (this.state.isRequired) {
item = <MyOwnInput attribute={'whatever'} />
} else {
item = <MyOwnInput />
}
return (
<div>
{item}
</div>
);
}
Dans React, vous pouvez restituer sous condition les composants mais également leurs attributs tels que props, className, id, etc.
Dans React, il est très judicieux d'utiliser "opérateur ternaire", qui peut vous aider à restituer des composants de manière conditionnelle.
L'exemple montre également comment rendre sous condition le composant et son attribut de style
Voici un exemple simple:
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>
Compte tenu de cet article JSX In Depth vous pouvez résoudre votre problème de cette façon
if (isRequired) {
return (
<MyOwnInput name="test" required='required' />
);
}
return (
<MyOwnInput name="test" />
);