我的理解是 propTypes 的目的是让您(和其他开发人员)知道组件应该期望什么 props,如果违反,React 会发出警告。
这是对的。
在这种情况下,约定是什么?
我不认为你会找到一个明确的答案。有些人会争辩说,如果你定义一个propType
,你应该定义所有预期的道具类型。其他人会说,就像您所做的那样,它不会由父组件(不包括 HOC)提供,所以为什么要打扰。还有一类人会告诉你根本不用担心propTypes
......
就个人而言,我属于第一类或最后一类:
- 如果该组件是供其他人使用的,例如普通的 ui 组件(例如 TextField、Button 等)或库的接口,则
propTypes
很有帮助,您应该将它们全部定义。
- 如果组件仅用于特定目的,在单个应用程序中,那么通常完全不用担心它们,因为当传递错误的 props 时,你将花费更多的时间来维护它们而不是调试(尤其是如果你编写小型、易于使用的功能组件)。
包含 的routerProps
理由是为了保护您免受withRouter
将来更改时提供的道具的更改。
因此,假设您要包含propTypes
forwithRouter
那么我们需要分解它们实际上应该是什么:
const Menu = ({ userId, ...routerProps}) => {
const { pathname } = routerProps.location
return (
// Something using userID
// Something using pathname
)
}
查看上面的代码片段,您可能认为propTypes
应该是
Menu.propTypes = {
userId: PropTypes.number.isRequired,
routerProps: PropTypes.object.isRequired
}
但是你会弄错了......前两行包含很多props
转换。其实应该是
Menu.propTypes = {
userId: PropTypes.number.isRequired,
location: PropTypes.shape({
pathname: PropTypes.string.isRequired
}).isRequired
}
为什么?该片段等效于:
const Menu = (props) => {
const userId = props.userId
const routerProps = Object.assign({}, props, { userId: undefined }
const pathname = routerProps.location.pathname
return (
// Something using userID
// Something using pathname
)
}
如您所见,routerProps
实际上根本不存在props
。
...routerProps
是一个休息参数,因此它获取 的所有其他值props
,在这种情况下,location
(可能还有其他您不关心的事情)。
希望有帮助。