在我的React 16应用中,我具有以下渲染功能:
render() {
const {
isLoading,
leverJobData,
isApiError
} = this.state;
return (
<Openings.Container>
<Openings.StyledH4>Open roles:</Openings.StyledH4>
{isLoading && <h4>Loading...</h4>}
{!isLoading && isApiError && <h4>Something went wrong. Please try again later!</h4>}
{!isLoading && !isApiError && leverJobData.length === 0 && (
<h4>There are no openings at this time.</h4>
)}
{!isLoading && !isApiError && leverJobData.length > 0 && (
<>{this.renderJobOpenings(leverJobData)}</>
)}
</Openings.Container>
);
}
是否有更干净的方法编写以上内容,还是在React中进行条件渲染的正确方法?
答案 0 :(得分:2)
当我有这样的障碍时,我喜欢打破条件并确切描述他们在做什么。例如:
render() {
const {
isLoading,
leverJobData,
isApiError
} = this.state;
const hasError = !isLoading && isApiError;
const noJobsAvailable = !isLoading && !isApiError && leverJobData.length === 0;
const hasJobsAvailable = !isLoading && !isApiError && leverJobData.length > 0;
return (
<Openings.Container>
<Openings.StyledH4>Open roles:</Openings.StyledH4>
{isLoading && <h4>Loading...</h4>}
{hasError && <h4>Something went wrong. Please try again later!</h4>}
{noJobsAvailable && <h4>There are no openings at this time.</h4>}
{hasJobsAvailable && this.renderJobOpenings(leverJobData)}
</Openings.Container>
);
}
答案 1 :(得分:1)
您还可以考虑包装类似的条件,例如:
const meow = () => {
const {
isLoading,
leverJobData,
isApiError
} = this.state;
return (
<Openings.Container>
<Openings.StyledH4>Open roles:</Openings.StyledH4>
{
!isLoading ?
!isApiError ?
leverJobData.length > 0 ?
<>{this.renderJobOpenings(leverJobData)}</> :
<h4>There are no openings at this time.</h4>
:
<h4>Something went wrong. Please try again later!</h4>
: <h4>Loading...</h4>
}
</Openings.Container>
);
}
答案 2 :(得分:-1)
编写此结构最容易理解的方法是使用状态机。这可以通过switch
语句来完成:
const IS_LOADING = 1;
const API_ERROR = 2;
const LEVER_JOB_DATA = 3;
_renderStatus = (status) => {
switch(currentStatus) {
case LOADING:
return <h4>Loading...</h4>;
case API_ERROR:
return <h4>Something went wrong. Please try again later!</h4>;
case LEVER_JOB_DATA:
// inside renderJobsOpenings you handle empty state
const {leverJobData} = this.state;
return this.renderJobOpenings(leverJobData);
default:
// or make sure to render a proper invalid state information
return null;
}
}
render() {
const {currentStatus} = this.state;
return (
<Openings.Container>
{ this._renderStatus(currentStatus) }
</Openings.Container>
);
}
避免嵌套三元运算。真的很难阅读。
最好的解决方法是使用useReducer钩子。这样,您可以通过一次副作用调用(setState)在许多接触点上进行适当的状态更改
答案 3 :(得分:-1)
我会做这样的事情:
class MyComponent extends React.Component {
render = () => {
const { isLoading, isApiError, leverJobData } = this.state;
const Content = () => {
if (isLoading) return <h4>Loading...</h4>;
else if (isApiError) return <h4>Something went wrong. Please try again later!</h4>;
else if (leverJobData.length === 0) return <h4>There are no openings at this time.</h4>;
else if (leverJobData.length > 0) return <h2>{this.renderJobOpenings(leverJobData)}</h2>;
};
return <Content />
}
}
这确实增加了组件的额外步骤,但是实际渲染有点“干净”。