我有一个React组件,在组件的渲染方法中,我有这样的东西:
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ switch(...) {} }
<div>
// removed for brevity
</div>
</div>
);
}
Now the point is that I have two div elements, one at the top and one at the bottom, that are fixed. In the middle I want to have a switch statement, and according to a value in my state I want to render a different component. So basically, I want the two div elements to be fixed always, and just in the middle to render a different component each time. I'm using this to implement a multi-step payment procedure). Though, as is the code currently it doesn't work, as it gives me an error saying that switch is unexpected. Any ideas how to achieve what I want?
这个答案专门用来解决@tonyfat提出的“重复”问题,关于如何使用条件表达式来处理相同的任务。
Avoiding statements here seems like more trouble than it's worth, but this script does the job as the snippet demonstrates:
// 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})`) }
这个助手应该可以做到这一点。
使用示例:
{componentSwitch(3, (switcher => switcher
.case(1, () =>
<p>It is one</p>
)
.case(2, () =>
<p>It is two</p>
)
.default(() =>
<p>It is something different</p>
)
))}
助手:
interface SwitchCases<T> {
case: (value: T, result: () => React.ReactNode) => SwitchCases<T>;
default: (result: () => React.ReactNode) => SwitchCases<T>;
}
export function componentSwitch<T>(value: T, cases: (cases: SwitchCases<T>) => void) {
var possibleCases: { value: T, result: () => React.ReactNode }[] = [];
var defaultResult: (() => React.ReactNode) | null = null;
var getSwitchCases: () => SwitchCases<T> = () => ({
case: (value: T, result: () => React.ReactNode) => {
possibleCases.push({ value: value, result });
return getSwitchCases();
},
default: (result: () => React.ReactNode) => {
defaultResult = result;
return getSwitchCases();
},
})
// getSwitchCases is recursive and will add all possible cases to the possibleCases array and sets defaultResult.
cases(getSwitchCases());
// Check if one of the cases is met
for(const possibleCase of possibleCases) {
if (possibleCase.value === value) {
return possibleCase.result();
}
}
// Check if the default case is defined
if (defaultResult) {
// Typescript wrongly assumes that defaultResult is always null.
var fixedDefaultResult = defaultResult as (() => React.ReactNode);
return fixedDefaultResult();
}
// None of the cases were met and default was not defined.
return undefined;
}