简单聊一聊如何处理 React props 是 null 的情况
hacker0limbo opened this issue · 0 comments
水文一篇...
场景
两个组件: App
和 Hello
// Hello.js
import React from "react";
export default function Hello(props) {
const { name = "mike" } = props;
return <div>Hello {name}</div>;
}
// App.js
import React from "react";
import Hello from "./Hello";
export default function App() {
return (
<div>
<Hello name={null} />
</div>
);
}
// renders Hello
我当时天真的以为这里会渲染 Hello mike
. 实际上最后渲染的是 Hello
...
另这里用 es6 的对象解构默认参数还是用 react 提供的 defaultProps
效果都是一样的
原因
去查了一下 MDN 的 Default parameters 以及 Destructuring assignment
, 果然是我疏忽了:
Default function parameters allow named parameters to be initialized with default values if no value or
undefined
is passed.
A variable can be assigned a default, in the case that the value unpacked from the object is
undefined
.
MDN 下的例子非常生动形象的解释了:
In the second call in this example, even if the first argument is set explicitly to
undefined
(though notnull
or otherfalsy
values), the value of thenum
argument is still the default.
function test(num = 1) {
console.log(typeof num)
}
test() // 'number' (num is set to 1)
test(undefined) // 'number' (num is set to 1 too)
// test with other falsy values:
test('') // 'string' (num is set to '')
test(null) // 'object' (num is set to null)
以及, React 官方有一个 issue 专门对于这个现象的讨论: null props considered differently in getDefaultProps vs. isRequired #2166
总结来讲就是(具体细节不细纠结了...网上应该很多文章大讲特讲这两个的区别):
null
是一个定义过的的值, 这个值是存在的, 虽然这个值代表了啥都没有undefined
这个值根本不存在
所以上面的组件想要触发默认 props 需要这么做:
<Hello name={undefined} />
<Hello />
// renders Hello mike
解决办法?
其实我没找到最佳实践, 因为有好多种写法可以规避 null 的出现. 但是我在 stackoverflow 上搜到了一个类似的问题: React.js - default prop is not used with null
is passed, 最高票答案是这样的(56 个赞), 以我的例子举例:
You can change the null value to undefined to use the default value.
<Hello name={getName() || undefined} />
好的...