我想知道在将用第三方HOC包装的组件上定义propTypes
的最佳实践是什么,在这种情况下,withRouter()
来自React-Router
。
我的理解是,propTypes
的要点是您(和其他开发人员(知道组件应该期望的道具,如果违反了该组件,则会发出警告。
因此,由于有关位置的道具已经由withRouter()
传递而没有人为干预,因此在这里是否有必要担心它们?
这是我正在使用的组件:
const Menu = ({ userId, ...routerProps}) => {
const { pathname } = routerProps.location
return (
// Something using userID
// Something using pathname
)
}
Menu.propTypes = {
userId: PropTypes.number.isRequired,
// routerProps: PropTypes.object.isRequired,
// ^ this is undefined, bc withRouter passes it in later?
}
export default withRouter(Menu)
//.... in parent:
<Menu userId={id} />
在这种情况下,约定是什么?
我的理解是,主体的要点是您(和其他开发人员(知道组件应该期望的道具,如果违反这一点,则会发出警告。
这是正确的。
在这种情况下的约定是什么?
我认为您不会为此找到明确的答案。有些人会争辩说,如果您定义一个propType
,则应定义所有预期的道具类型。其他人会说,就像您一样,它不会由父部件(不包括HOC(提供,所以为什么要打扰。还有另一类的人会告诉您不要担心propTypes
...
就个人而言,我属于第一个或最后一个类别:
- 如果该组件用于其他人的消费,例如通用UI组件(例如TextField,按钮等(或库的接口,则
propTypes
是有用的,您应该全部定义它们。 - 如果组件仅用于特定目的,则在一个应用程序中,通常不必担心它们,因为您会花更多的时间维护它们,而不是在通过错误的道具时进行调试(尤其是如果您正在编写小型,易于消耗功能组件(。
包括routerProps
的论点是保护您免受withRouter
将来提供的道具的更改。
因此,假设您想为withRouter
包含propTypes
,那么我们需要分解它们应该是什么:
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
}
但是您会误会...前2行包装在许多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
(也许还有其他您不在乎的事情(。
希望会有所帮助。