Jak warunkowo dodać atrybuty do komponentów Reactowych?
Czy istnieje sposób na dodanie atrybutów do komponentu Reactowego tylko wtedy, gdy spełniony jest określony warunek?
Powinienem dodać wymagane i readOnly atrybuty do tworzenia elementów na podstawie wywołania Ajax po renderowaniu, ale nie widzę, jak to rozwiązać, ponieważ readOnly= "false" nie jest tym samym, co całkowite pominięcie atrybutu.
Poniższy przykład powinien wyjaśnić, czego chcę, ale to nie zadziała (błąd Parse: Unexpected identifier).
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" : ""} />
);
}
});
14 answers
Najwyraźniej w przypadku pewnych atrybutów React jest wystarczająco inteligentny, aby pominąć atrybut, jeśli przekazywana wartość nie jest prawdziwa. Na przykład:
const InputComponent = function() {
const required = true;
const disabled = false;
return (
<input type="text" disabled={disabled} required={required} />
);
}
Spowoduje:
<input type="text" required>
Update: jeśli ktoś jest ciekawy jak/dlaczego tak się dzieje, szczegóły można znaleźć w kodzie źródłowym ReactDOM, a konkretnie w wierszach 30 oraz 167 z DOMProperty.plik js.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-13 09:35:42
Odpowiedź Juandemarco jest zwykle poprawna, ale tutaj jest inna opcja.
Zbuduj obiekt jak chcesz:
var inputProps = {
value: 'foo',
onChange: this.handleChange
};
if (condition)
inputProps.disabled = true;
Renderuj z spreadem, opcjonalnie przekazując również inne właściwości.
<input
value="this is overridden by inputProps"
{...inputProps}
onChange={overridesInputProps}
/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:03:22
Oto przykład użycia Bootstrap's Button
via React-Bootstrap (wersja 0.32.4):
var condition = true;
return (
<Button {...(condition ? {bsStyle: 'success'} : {})} />
);
W zależności od warunku zostaną zwrócone {bsStyle: 'success'}
lub {}
. Operator spread rozprzestrzeni następnie Właściwości zwracanego obiektu na komponent Button
. W przypadku falsy, ponieważ na zwracanym obiekcie nie istnieją żadne właściwości, nic nie zostanie przekazane do komponentu.
Alternatywny sposób oparty na komentarz Andy ' ego Polhilla :
var condition = true;
return (
<Button bsStyle={condition ? 'success' : undefined} />
);
Jedyną małą różnicą jest to, że w drugim przykładzie wewnętrzny składnik <Button/>
'S props
obiekt będzie miał klucz bsStyle
o wartości undefined
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:06:05
Oto alternatywa.
var condition = true;
var props = {
value: 'foo',
...( condition && { disabled: true } )
};
var component = <div { ...props } />;
Lub jego wersja inline
var condition = true;
var component = (
<div
value="foo"
{ ...( condition && { disabled: true } ) } />
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:09:42
Tak to zrobię.
Z warunkowym :
<Label
{...{
text: label,
type,
...(tooltip && { tooltip }),
isRequired: required
}}
/>
Nadal wolę używać regularnego sposobu przekazywania rekwizytów w dół, ponieważ jest on bardziej czytelny (moim zdaniem) w przypadku nie mają żadnych warunków.
Bez warunku :
<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:20:00
Powiedzmy, że chcemy dodać właściwość niestandardową (używając aria - * lub data -*), jeśli warunek jest prawdziwy:
{...this.props.isTrue && {'aria-name' : 'something here'}}
Powiedzmy, że chcemy dodać właściwość stylu, jeśli warunek jest prawdziwy:
{...this.props.isTrue && {style : {color: 'red'}}}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:11:28
Możesz użyć tego samego skrótu, który służy do dodawania/usuwania (części) komponentów ({isVisible && <SomeComponent />}
).
class MyComponent extends React.Component {
render() {
return (
<div someAttribute={someCondition && someValue} />
);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-24 14:49:12
Jeśli używasz ECMAScript 6, możesz po prostu napisać tak.
// First, create a wrap object.
const wrap = {
[variableName]: true
}
// Then, use it
<SomeComponent {...{wrap}} />
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:12:43
To powinno zadziałać, ponieważ twój stan zmieni się po wywołaniu Ajax, a komponent macierzysty ponownie wyrenderuje.
render : function () {
var item;
if (this.state.isRequired) {
item = <MyOwnInput attribute={'whatever'} />
} else {
item = <MyOwnInput />
}
return (
<div>
{item}
</div>
);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 00:59:37
W Reaccie możesz warunkowo renderować komponenty, ale także ich atrybuty, takie jak props, className, id i inne.
W Reaccie bardzo dobrą praktyką jest używanie operatora ternary , który może pomóc w warunkowym renderowaniu komponentów.
Przykład pokazuje również, jak warunkowo renderować komponent i jego atrybut stylu.
Oto prosty przykład:
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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:18:32
Na przykład Używanie stylów właściwości dla niestandardowego kontenera
const DriverSelector = props => {
const Container = props.container;
const otherProps = {
...( props.containerStyles && { style: props.containerStyles } )
};
return (
<Container {...otherProps} >
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-12 15:30:33
Rozważając post JSX w głębi, możesz rozwiązać swój problem w ten sposób:
if (isRequired) {
return (
<MyOwnInput name="test" required='required' />
);
}
return (
<MyOwnInput name="test" />
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 01:01:18
Z mojego punktu widzenia najlepszym sposobem zarządzania wieloma rekwizytami warunkowymi jest props object podejście @brigand. Ale można go poprawić, aby uniknąć dodawania jednego if
bloku dla każdego warunkowego propa.
Pomocnik ifVal
Zmień nazwę jak chcesz (iv, condVal, CV,_,...)
Możesz zdefiniować funkcję pomocniczą, która zwróci wartość, lub inną, jeśli spełniony jest warunek:
// components-helpers.js
export const ifVal = (cond, trueValue=true, falseValue=null) => {
return cond ? trueValue : falseValue
}
If cond
is true
(or truthy ), the trueValue
jest zwracane-lub true
.
Jeśli cond
jest false
(lub falsy ), zwraca się falseValue
- lub null
.
Te wartości domyślne (true
i null
) są zazwyczaj wartościami pozwalającymi na przekazanie właściwości do komponentu Reactowego. Możesz myśleć o tej funkcji jako o "ulepszonym operatorze trójdzielnym Reacta". Popraw go, jeśli potrzebujesz większej kontroli nad zwracanymi wartościami.
Użyjmy go z wieloma rekwizytami.
Zbuduj obiekt (złożony) props
// your-code.js
import { ifVal } from './components-helpers.js'
// BE SURE to replace all true/false with a real condition in you code
// this is just an example
const inputProps = {
value: 'foo',
enabled: ifVal(true), // true
noProp: ifVal(false), // null - ignored by React
aProp: ifVal(true, 'my value'), // 'my value'
bProp: ifVal(false, 'the true text', 'the false text') // 'my false value',
onAction: ifVal(isGuest, handleGuest, handleUser) // it depends on isGuest value
};
<MyComponent {...inputProps} />
To podejście jest podobne do popularnego sposobu warunkowego zarządzania klasami za pomocą narzędzia classnames , ale dostosowane do właściwości.
Dlaczego warto stosować to podejście
Będziesz miał czystą i czytelną składnię, nawet z wieloma rekwizytami warunkowymi: każdy nowy rekwizytor wystarczy dodać wiersz kodu wewnątrz deklaracji obiektu.
W ten sposób zamieniasz szum składniowy powtarzających się operatorów (...
, &&
, ? :
, ...), które mogą być bardzo irytujące, gdy masz wiele rekwizytów, z prostym wywołaniem funkcji.
Naszym priorytetem, jako programistów, jest napisanie najbardziej oczywistego kodu, który rozwiąże problem. Zbyt wiele razy rozwiązujemy problemy dla naszego ego , dodając złożoności tam, gdzie nie jest to wymagane. Nasz Kodeks powinien być prosty, dla nas dzisiaj, dla nas jutro i dla naszych kolegów.
To, że możemy coś zrobić, nie znaczy, że powinniśmy.]}
Mam nadzieję, że ta późna odpowiedź pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-23 09:40:53
Myślę, że może to być przydatne dla tych, którzy chcieliby, aby wartość atrybutu była funkcją:
import { RNCamera } from 'react-native-camera';
[...]
export default class MyView extends React.Component {
_myFunction = (myObject) => {
console.log(myObject.type); //
}
render() {
var scannerProps = Platform.OS === 'ios' ?
{
onBarCodeRead : this._myFunction
}
:
{
// here you can add attribute(s) for other platforms
}
return (
// it is just a part of code for MyView's layout
<RNCamera
ref={ref => { this.camera = ref; }}
style={{ flex: 1, justifyContent: 'flex-end', alignItems: 'center', }}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
{...scannerProps}
/>
);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-14 10:56:25