我有这个React组件,它可以有4种状态:advisoryResults,results,noResults和newAccount。
我认为使用三元表达式来这样做是有道理的,但这是不允许的,对此有什么好的选择?
export default class Home extends React.Component {
state = {
isAdmin: false
};
render() {
const { isAdmin } = this.state;
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin ? (
<Button
onClick={this.handleAddNewContact }
>
Add new Contact
</Button>
) : (
''
)}
{searchMode === searchModes.advisoryPanels ? (
<>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</>
) : searchMode === searchModes.noResultsPanel ? (
<SearchNoResultsPanel />
) : searchMode === searchModes.resultsPanel ? (
accountInfo.map((info, index) => (
<SearchResultPanel info={info} isAdmin={isAdmin} key={index} />
))
) : searchMode === searchModes.addContactPanel ? (
<AddNewContactForm
onCancelAccount={this.onCancelAccount}
onSaveAccount={this.onSaveAccount}
/>
) : null}
</div>
</div>
);
}
}
请告知。
答案 0 :(得分:2)
我建议做这样的事情:
export default class Home extends React.Component {
state = {
isAdmin: false
};
onCancelAccount = () => {};
onSaveAcciont = () => {};
renderSearchResults = (searchMode) => {
const { info, isAdmin, index } = this.props;
switch (searchMode) {
case searchModes.advisoryPanels:
return this.renderAdvisoryPanels();
case searchModes.noResultsPanel:
return <SearchNoResultsPanel />;
case searchModes.resultsPanel:
return <SearchResultPanel info={info} isAdmin={isAdmin} key={index} />;
case searchModes.addContactPanel:
return (
<AddNewContactForm
onCancelAccount={this.onCancelAccount}
onSaveAccount={this.onSaveAccount}
/>
);
default:
return null;
}
}
renderAdvisoryPanels = () => (
<React.Fragment>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</React.Fragment>
);
render() {
const { isAdmin } = this.state;
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin && (
<Button onClick={this.handleAddNewContact}>Add new Contact</Button>
)}
{this.renderSearchResults(searchMode)}
</div>
</div>
);
}
}
某些处理程序/道具在您的示例中无法立即看到,因此,如果我遇到问题,请解决。
答案 1 :(得分:0)
当您用switch语句问这个问题时,我正要写一个答案。
使用包含所有可能结果的JSON可以解决您的问题,而无需添加不必要的代码:
render() {
const { isAdmin } = this.state;
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin && <Button onClick={this.handleAddNewContact}> Add new Contact</Button>}
{
{
[searchModes.SearchAdvisoryPanels]: (
<>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</>
),
[searchModes.noResultsPanel]: <SearchNoResultsPanel />,
[searchModes.resultsPanel]: accountInfo.map((info, index) => (<SearchResultPanel info={info} isAdmin={isAdmin} key={index} />)),
[searchModes.addContactPanel]: <AddNewContactForm onCancelAccount={this.onCancelAccount} onSaveAccount={this.onSaveAccount} />
}[searchMode]
}
</div>
</div>
);
}
但是,即使未显示所有组件,此解决方案也将安装所有组件,而使用箭头功能可以通过仅安装所需组件来提高性能:
render() {
const { isAdmin } = this.state;
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin && <Button onClick={this.handleAddNewContact}> Add new Contact</Button>}
{
{
[searchModes.SearchAdvisoryPanels]: () => (
<>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</>
),
[searchModes.noResultsPanel]: () => <SearchNoResultsPanel />,
[searchModes.resultsPanel]: () => accountInfo.map((info, index) => (<SearchResultPanel info={info} isAdmin={isAdmin} key={index} />)),
[searchModes.addContactPanel]: () => <AddNewContactForm onCancelAccount={this.onCancelAccount} onSaveAccount={this.onSaveAccount} />
}[searchMode]()
}
</div>
</div>
);
}
编辑
如果变量的值可以不同于每个给定的选项,则可以实现以下解决方案。
如果值未定义,则发送不执行任何操作的函数:
}[searchMode] || (x => x)()
或将结果存储在返回值之外,并调用该函数(如果存在):
render() {
const { isAdmin } = this.state;
const searchRender = {
[searchModes.SearchAdvisoryPanels]: () => (
<>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</>
),
[searchModes.noResultsPanel]: () => <SearchNoResultsPanel />,
[searchModes.resultsPanel]: () => accountInfo.map((info, index) => (<SearchResultPanel info={info} isAdmin={isAdmin} key={index} />)),
[searchModes.addContactPanel]: () => <AddNewContactForm onCancelAccount={this.onCancelAccount} onSaveAccount={this.onSaveAccount} />
}[searchMode]
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin && <Button onClick={this.handleAddNewContact}> Add new Contact</Button>}
{searchRender && searchRender()}
</div>
</div>
);
}
编辑:这是什么黑魔法?
第一步是使用computed properties创建JSON,它允许您从变量而不是硬编码值中分配对象键:
const searchModes = {
SearchAdvisoryPanels: "a",
noResultsPanel: "b",
resultsPanel: "c",
addContactPanel: "d"
}
const result = {
[searchModes.SearchAdvisoryPanels]: 1,
[searchModes.noResultsPanel]: 2 ,
[searchModes.resultsPanel]: 3,
[searchModes.addContactPanel]: 4
}
console.log(result)
我们现在可以将1 2 3 4
替换为所需的值。在这种情况下,箭头起作用。要获得所需的结果,只需在JSON的末尾添加大括号:
const searchModes = {
SearchAdvisoryPanels: "a",
noResultsPanel: "b",
resultsPanel: "c",
addContactPanel: "d"
}
const search = "c"
const result = {
[searchModes.SearchAdvisoryPanels]: 1,
[searchModes.noResultsPanel]: 2 ,
[searchModes.resultsPanel]: 3,
[searchModes.addContactPanel]: 4
}[search]
console.log(result)
如果将返回的值转换为函数,则只需在其末尾加上括号即可:
const searchModes = {
SearchAdvisoryPanels: "a",
noResultsPanel: "b",
resultsPanel: "c",
addContactPanel: "d"
}
const search = "c"
const result = {
[searchModes.SearchAdvisoryPanels]: () => 1,
[searchModes.noResultsPanel]: () => 2 ,
[searchModes.resultsPanel]: () => 3,
[searchModes.addContactPanel]: () => 4
}[search]()
console.log('Short : ' + result)
//Long syntax :
const options = {
[searchModes.SearchAdvisoryPanels]: () => 1,
[searchModes.noResultsPanel]: () => 2 ,
[searchModes.resultsPanel]: () => 3,
[searchModes.addContactPanel]: () => 4
}
const action = options[search]
const output = action()
console.log('Long : ' + output)
答案 2 :(得分:0)
这是您应该在JS上进行的工作,然后将内容移动到fn。这种方法使渲染fn保持清晰。您的getSearchMode读数清晰,没有复杂的动作。您不会设置不必要的对象,不会在渲染函数内创建许多函数,也不会做任何魔术-只是普通的旧JS。
export default class Home extends React.Component {
state = {
isAdmin: false,
}
getSearchMode = (searchMode) => {
if (searchMode === searchModes.advisoryPanels) {
return (
<>
<SearchAdvisoryPanels />
<div css={{ textAlign: 'center', margin: '60px auto' }}>
<ManAtDesk />
</div>
</>
)
}
if (searchMode === searchModes.noResultsPanel) {
return <SearchNoResultsPanel />
}
if (searchMode === searchModes.resultsPanel) {
return accountInfo.map((info, index) => (
<SearchResultPanel info={info} isAdmin={this.state.isAdmin} key={index} /> // you should not use index as key
))
}
if (searchMode === searchModes.addContactPanel) {
return (
<AddNewContactForm
onCancelAccount={this.onCancelAccount}
onSaveAccount={this.onSaveAccount}
/>
)
}
return null
}
render() {
const { isAdmin } = this.state
return (
<div>
<Header />
<div css={innerWrap}>
{isAdmin ? <Button onClick={this.handleAddNewContact}>Add new Contact</Button> : ''}
{this.getSearchMode(searchMode)}
</div>
</div>
)
}
}