我正试图让多层条件渲染在反应中工作,我遇到了问题。
我已经将我的用例简化为下面的代码:
{data &&
dataIsLoading
? <h1> Loading <h1>
: !data.isError
? <Component data={data} />
: <h1> Error <h1>
}
我希望上面代码片段的行为是
- 检查数据是否存在-如果存在
- 检查数据是否正在加载-如果是,显示'loading',如果不是
- 检查数据是否有错误-如果有显示'error',如果没有
- 显示数据
不幸的是,当运行此代码时,我得到一个Null引用异常,当试图评估!data.isError
。如果data为null,那一行就不应该被执行——这就是条件呈现的意义所在!
我试过明确地检查data !== null &&
,我试过用简单的{false &&
代替{data &&
,我仍然遇到同样的问题。如果我误解了react条件渲染的工作原理,我如何在这种情况下安全地防止null值。
嵌套条件可能很难阅读。条件运算符接受三个操作数:¹
条件- 计算条件是否为真的操作数
- 计算条件是否为false的操作数
最外层条件的操作数是:
data && dataIsLoading
<h1> Loading <h1>
!data.isError ? <Component data={data} /> : <h1> Error <h1>
请注意,data &&
部分只是最外层条件的一部分,而不是嵌套条件的一部分。因此,当data && dataIsLoading
为假时(因为data
为null
),!data.isError ? <Component data={data} /> : <h1> Error <h1>
被求值-并且失败,因为data
为空。
最小更改的修复是将()
放在data &&
之后的所有内容:
{data && (
dataIsLoading
? <h1> Loading <h1>
: !data.isError
? <Component data={data} />
: <h1> Error <h1>
)}
…但是您可以考虑在JSX表达式之前将其分解为代码,以使其更易于阅读和维护。
¹这就是为什么它有时被称为"三元运算符"(一元运算符接受一个操作数,二元运算符接受两个操作数,三元接受三个操作数,…)它恰好是JavaScript目前唯一的三元操作符,但这可能会改变。
我把一个小沙盒放在一起,它显示了您可能遇到的一些不同状态:https://codesandbox.io/s/epic-tereshkova-g60xy重要的部分在下面。当您检查data && dataIsLoading
并返回false时,然后您转到下一个检查!data.isError
,但如果data = undefined
则data.isError
将抛出错误。您可以将此条件展开,检查data
是否存在,然后计算!data.isError
。
<div className="App">
{data && dataIsLoading ? (
<h1> Loading </h1>
) : data && !data.isError ? (
<h1> All good </h1>
) : (
<h1> Error </h1>
)}
</div>
你说你正在使用React,对吗?所以,让我给你我的5美分。对我来说,下面的代码是更好的编写方式:
{
dataIsLoading ? (
<h1>Loading</h1>
) : (
<>
{
data.isError ? (
<h1>Error</h1>
) : (
<Component data={data} />
)
}
</>
)
}
…通过这种方式,你的代码更容易理解,你可以直接删除双重检查,因为第一个将检查加载,第二个,在片段中,将进行数据检查。
PS:还有一件很重要的事…我看到在你的代码,很多标签未关闭,像H1标签。这每次都会带来麻烦。我建议你使用EsLint或Prettier来帮助你。