[英]Do not nest ternary expressions - Way to change between 3 styles based on coditions
[英]Do not nest ternary expression - alternative
我有這個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>
);
}
}
請指教。
我建議做這樣的事情:
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>
);
}
}
從您的示例中無法立即看到某些處理程序/屬性,因此,如果我遇到問題,請進行修復。
當您用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>
);
}
編輯:這是什么黑魔法?
第一步創建具有計算屬性的JSON,它允許您從變量而不是硬編碼值分配Objects鍵:
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)
這是您應該在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>
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.