我想知道在将使用第三方HOC包装的组件上定义propTypes
的最佳做法是什么,在这种情况下,withRouter()
来自React-Router
。< / p>
我的理解是propTypes
的意思是你(和其他开发者)知道组件应该期望什么道具,如果违反了,React会发出警告。
因此,由于关于位置的道具已经由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} />
在这种情况下会有什么约定?
答案 0 :(得分:2)
我的理解是propTypes的重点在于你(和其他开发人员)知道组件应该期望什么道具,如果违反了,React会发出警告。
这是正确的。
在这种情况下会有什么约定?
我认为你不会找到明确的答案。有些人会争辩说,如果你定义一个propType
,你应该定义所有预期的道具类型。其他人会像你一样说,它不会由父组件(不包括HOC)提供,所以为什么要这么麻烦。还有另一类人会告诉你根本不用担心propTypes
...
就个人而言,我属于第一类或最后一类:
propTypes
是有用的,您应该将它们全部定义包含routerProps
的论据是保护您免受withRouter
提供的道具的更改,如果它们将来发生变化。
因此,假设您要为propTypes
添加withRouter
,那么我们需要细分它们实际应该是什么:
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
是rest parameter,因此它会获得props
的所有其他值,在这种情况下,location
(也许还有其他你不关心的事情)
希望有所帮助。