我有一个React组件,在组件的render
方法中我有这样的东西:
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ switch(...) {} }
<div>
// removed for brevity
</div>
</div>
);
}
现在重点是我有两个div
元素,一个在顶部,一个在底部,是固定的。在中间我想要一个switch语句,根据我的状态中的值,我想渲染一个不同的组件。所以基本上,我希望始终修复两个div
元素,并且只是在中间每次渲染一个不同的组件。我用这个来实现多步付款程序)。虽然,代码目前它不起作用,因为它给我一个错误,说switch
是意外的。任何想法如何实现我想要的东西?
答案 0 :(得分:64)
试试这个,这也更清晰:在函数中从渲染中取出那个开关,然后调用它传递你想要的参数。例如:
SELECT BUILDINGNO.BUILDING, AVG(SESSIONPRICE.CONFERENCESESSION)
FROM BUILDING
JOIN CONFERENCESESSION ON BUILDINGNO.BUILDING = BUILDINGNO.CONFERENCESESSION
WHERE BUILDINGNO.BUILDING = SESSIONPRICE.CONFERENCESESSION
GROUP BY BUILDINGNO.BUILDING
Order by AVG(SESSIONPRICE.CONFERENCESESSION) DESC
limit 2;
&#13;
答案 1 :(得分:25)
发生了这种情况,因为<?php
$laborTotals = array();
$totalLaborDollars= 0;
$laborTotals[$laborAnalysis['jobcode']]['jobcode'] = $laborAnalysis['jobrole'];
$laborTotals[$laborAnalysis['jobcode']]['jobdescription'] = $laborAnalysis['jobdescription'];
$laborTotals[$laborAnalysis['jobcode']]['totalsalary'] += $laborAnalysis['totalsalary'];
}
foreach ($laborTotals as $labor) {
$html .= ' <tr>';
$html .= ' <td class="gridData">' . $labor['jobcode'] . '</td>';
$html .= ' <td class="gridData">' . $labor['jobdescription'] . '</td>';
$html .= ' <td class="gridData txtLeft"><b>$</b>' . number_format($labor['totalsalary'], 2, '.', ',') . '</td>';
$totalLaborDollars+=$labor['totalsalary'];
}
?>
语句是switch
,但这里javascript需要一个表达式。
虽然不建议在statement
方法中使用switch语句,但您可以使用自调用函数来实现此目的:
render
答案 2 :(得分:23)
与其他答案相反,我希望在render函数中内联“开关”。这样可以更清楚地知道在该位置可以渲染哪些组件。您可以使用普通的旧javascript对象来实现类似switch的表达式:
render () {
return (
<div>
<div>
{/* removed for brevity */}
</div>
{
{
'foo': <Foo />,
'bar': <Bar />
}[param]
}
<div>
{/* removed for brevity */}
</div>
</div>
)
}
答案 3 :(得分:14)
我不是当前答案的忠实拥护者,因为它们要么太冗长,要么要求您跳过代码以了解正在发生的事情。
我更喜欢通过创建<Switch/>
来使组件更集中地进行操作。该组件的工作是获取一个道具,并仅渲染其子道具与该道具匹配的子项。因此,在下面的示例中,我在开关上创建了一个test
道具,并将其与子项上的value
道具进行了比较,仅渲染了匹配的道具。
示例:
const Switch = props => {
const { test, children } = props
// filter out only children with a matching prop
return children.find(child => {
return child.props.value === test
})
}
const Sample = props => {
const someTest = true
return (
<Switch test={someTest}>
<div value={false}>Will display if someTest is false</div>
<div value={true}>Will display if someTest is true</div>
</Switch>
)
}
ReactDOM.render(
<Sample/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
您可以根据需要使开关简单或复杂。不要忘记对孩子及其价值道具进行更强大的检查。
答案 4 :(得分:7)
使用条件运算符在渲染块中表示一种开关情况的方法:
{this.props.someVar == 1 &&
<SomeContent/>
|| this.props.someVar == 2 &&
<SomeOtherContent />
|| this.props.someOtherVar == 1 &&
<YetSomeOtherContent />
||
<SomeDefaultContent />
}
我建议添加一些括号以确保获得预期结果,除非掌握运算符的优先级...
答案 5 :(得分:3)
怎么样:
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>
);
}
答案 6 :(得分:2)
这是一个完整的工作示例,其中使用按钮在组件之间进行切换
您可以按照以下说明设置构造函数
constructor(props)
{
super(props);
this.state={
currentView: ''
}
}
然后您可以按以下方式呈现组件
render()
{
const switchView = () => {
switch(this.state.currentView)
{
case "settings": return <h2>settings</h2>;
case "dashboard": return <h2>dashboard</h2>;
default: return <h2>dashboard</h2>
}
}
return (
<div>
<button onClick={(e) => this.setState({currentView: "settings"})}>settings</button>
<button onClick={(e) => this.setState({currentView: "dashboard"})}>dashboard</button>
<div className="container">
{ switchView() }
</div>
</div>
);
}
}
如您所见,我正在使用按钮在状态之间进行切换。
答案 7 :(得分:1)
我在render()方法中做到了这一点:
App.xaml
我试图使render()返回保持干净,因此我将逻辑放在上面的'const'函数中。这样,我也可以整齐地缩进我的开关盒。
答案 8 :(得分:1)
我真的很喜欢https://stackoverflow.com/a/60313570/770134中的建议,因此我将其修改为Typescript
import React, { FunctionComponent } from 'react'
import { Optional } from "typescript-optional";
const { ofNullable } = Optional
interface SwitchProps {
test: string
defaultComponent: JSX.Element
}
export const Switch: FunctionComponent<SwitchProps> = (props) => {
return ofNullable(props.children)
.map((children) => {
return ofNullable((children as JSX.Element[]).find((child) => child.props['value'] === props.test))
.orElse(props.defaultComponent)
})
.orElseThrow(() => new Error('Children are required for a switch component'))
}
const Foo = ({ value = "foo" }) => <div>foo</div>;
const Bar = ({ value = "bar" }) => <div>bar</div>;
const value = "foo";
const SwitchExample = <Switch test={value} defaultComponent={<div />}>
<Foo />
<Bar />
</Switch>;
答案 9 :(得分:1)
我将接受的答案转换为箭头功能组件解决方案,看到 James 提供了类似的答案,并且可能会出现错误 not defined
。所以这里是解决方案:
const renderSwitch = (param) => {
switch (param) {
case "foo":
return "bar";
default:
return "foo";
}
};
return (
<div>
<div></div>
{renderSwitch(param)}
<div></div>
</div>
);
答案 10 :(得分:0)
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
}
}
答案 11 :(得分:0)
您不能在渲染中进行切换。放置访问一个元素的对象文字的伪切换方法不是理想的,因为它会导致处理所有视图,并可能导致该状态下不存在的prop的依赖项错误。
这是一种很好的干净方法,不需要预先渲染每个视图:
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>
)
如果视图状态的条件不仅仅基于简单的属性(例如每行多个条件),那么枚举和getViewState
函数来封装条件是一种很好的方式来分隔条件逻辑和清理渲染。
答案 12 :(得分:0)
这是另一种方法。
render() {
return {this[`renderStep${this.state.step}`]()}
renderStep0() { return 'step 0' }
renderStep1() { return 'step 1' }
答案 13 :(得分:0)
你可以这样做。
<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 />
}
}
答案 14 :(得分:0)
我对任何答案都不是绝对满意。 但是我从@Matt Way那里学到了一些想法。
这是我的解决方案:
定义:
const Switch = props => {
const { test, children = null } = props;
return children && children.find(child => child && child.props && child.props.casevalue === test) || null;
}
const Case = ({ casevalue = false, children = null }) => <div casevalue={`${casevalue}`}>{children}</div>;
Case.propTypes = {
casevalue: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
}
const Default = ({ children }) => children || <h1>NO_RESULT</h1>;
const SwitchCase = ({ test, cases = [], defaultValue = null }) => {
const defaultVal = defaultValue
&& React.cloneElement(defaultValue, { key: 'default-key', casevalue: `${test}` })
|| <Default key='default-key' casevalue={`${test}`} />;
return (
<Switch test={`${test}`} >
{
cases.map((cas, i) => {
const { props = {} } = cas || {};
const { casevalue = false, ...rest } = props || {};
return <Case key={`case-key-${i}`} casevalue={`${casevalue}`}>{ React.cloneElement(cas, rest)}</Case>
})
.concat(defaultVal)
}
</Switch>
);
}
用法:
<SwitchCase
cases={[
<div casevalue={`${false}`}>#1</div>,
<div casevalue={`${true}`}>#2</div>,
<div casevalue={`${false}`}>#3</div>,
]}
defaultValue={<h1>...nothing to see here</h1>} // You can leave it blank.
test={`${true}`}
/>
答案 15 :(得分:0)
function Notification({ text, status }) {
return (
<div>
{(() => {
switch (status) {
case 'info':
return <Info text={text} />;
case 'warning':
return <Warning text={text} />;
case 'error':
return <Error text={text} />;
default:
return null;
}
})()}
</div>
);
}
答案 16 :(得分:0)
React 组件中的 Switch-Case 语句可以如下使用:
<div id="time-list">
{
(() => {
switch (groupByFilterId) {
case 0:/*Case 0 */
return (
<div>Case 0</div>
)
break;
case 1: /*Case 1 */
return (
<div>Case 1</div>
)
break;
case 2:/*Case 2 */
return (
<div>Case 2</div>
)
break;
}
})()}
</div>
答案 17 :(得分:0)
我知道我参加聚会有点晚了,但我认为这个实现可能会有所帮助
您可以使用条件运算符来渲染组件
如果你有以下 switch 语句
switch(value) {
case CASE1:
return <Case1Component/>
case CASE2:
return <Case2Component/>
case CASE3:
return <Case3Component/>
default:
return <DefaultComponent/>
}
你可以把它转换成这样的反应组件
const cases = [CASE0, CASE1, CASE2]
// Reminds me of 'react-router-dom'
return (
<div>
{value === cases[0] && <Case0Component/>}
{value === cases[1] && <Case1Component/>}
{value === cases[2] && <Case2Component/>}
{!cases.includes(value) && <DefaultComponent/>}
</div>
)
答案 18 :(得分:-1)
让它变得简单,只需使用许多 if 语句。
例如:
<Grid>
{yourVar==="val1"?(<> your code for val1 </>):nul}
{yourVar==="val2"?(<> your code for val2 </>):nul}
.... other statments
</Grid>
答案 19 :(得分:-1)
这个答案专门针对@tonyfat 的 this "duplicate" question 问题,关于如何使用条件表达式来处理相同的任务。
// Runs tests
let id = 0, flag = 0;
renderByFlag(id, flag); // jobId out of range
id = 1; // jobId in range
while(++flag < 5){ // active flag ranges from 1 to 4
renderByFlag(id, flag);
}
// Defines a function that chooses what to render based on two provided values
function renderByFlag(jobId, activeFlag){
jobId === 1 ? (
activeFlag === 1
? render("A (flag = 1)")
: activeFlag === 2
? render("B (flag = 2)")
: activeFlag === 3
? render("C (flag = 3)")
: pass(`flag ${activeFlag} out of range`)
)
: pass(`jobId ${jobId} out of range`)
}
// Defines logging functions for demo purposes
function render(val){ console.log(`Rendering ${val}`); }
function pass(reason){ console.log(`Doing nothing (${reason})`) }