问题说明
在开发React Native过程中,我们常常会根据一个变量的值是否为空来控制组件的显示与否。
一个简单的做法是{ someVariable && <Text>some text</Text> }
今天就因为写了这样的代码踩到了一个坑,导致App Crash了。
Error内容:RawText “” must be wrapped in an explicit
分析了一波,发现是数据问题导致的。当下面的代码中someVariable的值为空字符串''
的时候,就会出现这种Error。{ someVariable && <Text>some text</Text> }
测试结果
为了分析这个问题,针对someVariable为空的情况做了一些测试,结果如下:
case 1. { '' && <Text>some text</Text> }
=> 有Error,App会Crash
case 2. { 0 && <Text>some text</Text> }
=> 有Error,App会Crash
case 3. { null && <Text>some text</Text> }
=> 没有Error, <Text>
组件不会显示
case 4. { undefined && <Text>some text</Text> }
=> 没有Error, <Text>
组件不会显示
case 5. { NaN && <Text>some text</Text> }
=> 有Error,App会Crash
case 6. { [] && <Text>some text</Text> }
=> 没有Error, <Text>
组件会显示
case 7. { {} && <Text>some text</Text> }
=> 没有Error, <Text>
组件会显示
原因分析
为什么会出现以上结果呢?
为了分析这个问题首先需要明白expr1 && expr2
的含义。
这个表达式是说当expr1
为false的时候,会返回expr1
,否则会返回expr2
。
那么''
|0
|null
|undefined
|NaN
|[]
|{}
这些值到底是true还是false呢,我们可以在Chrome Console上面通过两个非操作!!
来测试一下。
从上面结果可以看到,''
|0
|null
|undefined
|NaN
的值是false,[]
|{}
的值为true。
好了,通过以上分析我们可以得到case 1 ~ case 6的结果如下:
case 1. { '' && <Text>some text</Text> }
=> { '' }
case 2. { 0 && <Text>some text</Text> }
=> { 0 }
case 3. { null && <Text>some text</Text> }
=> { null }
case 4. { undefined && <Text>some text</Text> }
=> { undefined }
case 5. { NaN && <Text>some text</Text> }
=> { NaN }
case 6. { [] && <Text>some text</Text> }
=> { <Text>some text</Text> }
case 7. { {} && <Text>some text</Text> }
=> { <Text>some text</Text> }
在React Native中{ '' }
|{ 0 }
|{ NaN }
会被当做文本字符串,必须要包含在<Text>
组件中,所以case 1、case 2、case 5会导致App Crash;case 3、case 4不会报错,也不会在页面上显示任何东西;case 5、case 6会在页面上显示some text
文本。
解决方案
为了规避App Crash的风险,有两个简单的方案来实现【根据变量的值是否为空来控制组件的显示与否】:
1.当变量类型为Object或Array时,可以使用lodash的isEmpty方法{ !_.isEmpty(someVariable) && <Text>some text</Text> }
2.当变量为其他类型时,使用两个非操作{ !!someVariable && <Text>some text</Text> }