Как использовать оператор switch внутри компонента React?
У меня есть компонент React, а внутри метода render
компонента у меня есть что-то вроде этого:
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ switch(...) {} }
<div>
// removed for brevity
</div>
</div>
);
}
Теперь дело в том, что у меня есть два элемента div
, один сверху и один внизу, которые фиксированы. В середине я хочу иметь оператор switch, и в соответствии со значением в моем состоянии я хочу отобразить другой компонент. Поэтому в основном, я хочу, чтобы оба элемента div
были исправлены всегда, и только посередине, чтобы каждый раз отображать разные компоненты. Я использую это для реализации многоступенчатой процедуры оплаты). Хотя, как и в настоящее время код не работает, поскольку он дает мне ошибку, говоря, что switch
неожиданен. Любые идеи, как достичь того, чего я хочу?
Ответы
Ответ 1
Попробуйте это, что также является более чистым: получите этот переключатель из рендеринга в функции и просто назовите его передачей параметров, которые вы хотите. Например:
renderSwitch(param) {
switch(param) {
case 'foo':
return 'bar';
default:
return 'foo';
}
}
render() {
return (
<div>
<div>
// removed for brevity
</div>
{this.renderSwitch(param)}
<div>
// removed for brevity
</div>
</div>
);
}
Ответ 2
Это происходит, потому что оператор switch
является statement
, но здесь javascript ожидает выражение.
Хотя, не рекомендуется использовать оператор switch в методе render
, вы можете использовать функцию self-invoking для достижения этого:
render() {
// Don't forget to return a value in a switch statement
return (
<div>
{(() => {
switch(...) {}
})()}
</div>
);
}
Ответ 3
В отличие от других ответов, я предпочел бы включить "переключатель" в функцию рендеринга. Это делает более понятным, какие компоненты могут быть сделаны в этом положении. Вы можете реализовать выражение, подобное выражению, используя простой старый объект javascript:
render () {
return (
<div>
<div>
{/* removed for brevity */}
</div>
{
{
'foo': <Foo />,
'bar': <Bar />
}[param]
}
<div>
{/* removed for brevity */}
</div>
</div>
)
}
Ответ 4
Способ представления вида регистра переключателя в блоке рендеринга с использованием условных операторов:
{this.props.someVar == 1 &&
<SomeContent/>
|| this.props.someVar == 2 &&
<SomeOtherContent />
|| this.props.someOtherVar == 1 &&
<YetSomeOtherContent />
||
<SomeDefaultContent />
}
Я советую добавить несколько скобок, чтобы быть уверенным в ожидаемом результате, если только вы не освоите приоритет операторов...
Ответ 5
Я сделал это внутри метода render():
render() {
const project = () => {
switch(this.projectName) {
case "one": return <ComponentA />;
case "two": return <ComponentB />;
case "three": return <ComponentC />;
case "four": return <ComponentD />;
default: return <h1>No project match</h1>
}
}
return (
<div>{ project() }</div>
)
}
Я попытался сохранить возвращаемое значение render() чистым, поэтому я поместил свою логику в функцию const прямо выше. Таким образом, я могу аккуратно делать отступы в своих переключателях.
Ответ 6
Как насчет:
mySwitchFunction = (param) => {
switch (param) {
case 'A':
return ([
<div />,
]);
// etc...
}
}
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ this.mySwitchFunction(param) }
<div>
// removed for brevity
</div>
</div>
);
}
Ответ 7
Ответ от Lenkan - отличное решение.
<div>
{{ beep: <div>Beep</div>,
boop: <div>Boop</div>
}[greeting]}
</div>
Если вам нужно значение по умолчанию, то вы можете даже сделать
<div>
{{ beep: <div>Beep</div>,
boop: <div>Boop</div>
}[greeting] || <div>Hello world</div>}
</div>
Кроме того, если это не очень хорошо для вас, то вы можете сделать что-то вроде
<div>
{
rswitch(greeting, {
beep: <div>Beep</div>,
boop: <div>Boop</div>,
default: <div>Hello world</div>
})
}
</div>
с
function rswitch (param, cases) {
if (cases[param]) {
return cases[param]
} else {
return cases.default
}
}
Ответ 8
Вы можете сделать что-то подобное.
<div>
{ object.map((item, index) => this.getComponent(item, index)) }
</div>
getComponent(item, index) {
switch (item.type) {
case '1':
return <Comp1/>
case '2':
return <Comp2/>
case '3':
return <Comp3 />
}
}
Ответ 9
Вы не можете иметь переключатель в рендере. Подход psuedo-switch для размещения объекта-литерала, который обращается к одному элементу, не идеален, потому что он вызывает обработку всех представлений, что может привести к ошибкам зависимости реквизитов, которые не существуют в этом состоянии.
Вот хороший чистый способ сделать это, который не требует, чтобы каждое представление отрисовывалось заранее:
render () {
const viewState = this.getViewState();
return (
<div>
{viewState === ViewState.NO_RESULTS && this.renderNoResults()}
{viewState === ViewState.LIST_RESULTS && this.renderResults()}
{viewState === ViewState.SUCCESS_DONE && this.renderCompleted()}
</div>
)
Если ваши условия, для которых состояние просмотра основано на чем-то большем, чем простое свойство - например, несколько условий на строку, тогда enum и функция getViewState
для инкапсуляции условий - хороший способ отделить эту условную логику и очистить ваш рендеринг.
Ответ 10
Это другой подход.
render() {
return {this['renderStep${this.state.step}']()}
renderStep0() { return 'step 0' }
renderStep1() { return 'step 1' }