如何为使用 withRouter 包裹的组件定义 propTypes?
How to define propTypes for a component wrapped with withRouter?
我想知道在将用第 3 方 HOC 包装的组件上定义 propTypes
的最佳实践是什么,在这种情况下,withRouter()
来自 React-Router
.
据我了解,propTypes
的目的是让您(和其他开发人员)知道组件应该期待什么道具,如果违反,React 会发出警告。
因此,关于位置的 props 已经被 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} />
这种情况下的惯例是什么?
It is my understanding that the point of propTypes is so you (and other developers) know what props a component should expect, and React will give warnings if this is violated.
这是正确的。
What would be the convention in this case?
我认为您不会找到明确的答案。有些人会争辩说,如果你定义一个 propType
你应该定义所有预期的道具类型。其他人会像您一样说,它不会由父组件(不包括 HOC)提供,所以何必呢。还有一类人会告诉你根本不用担心 propTypes
...
就个人而言,我属于第一类或最后一类:
- 如果组件是供其他人使用的,例如通用 ui 组件(例如 TextField、Button 等)或库的界面,那么
propTypes
很有帮助,你应该定义它们。
- 如果组件仅用于特定目的,在单个应用程序中,那么通常根本不用担心它们,因为在传递错误的 props 时,您将花费更多的时间来维护它们而不是调试 (特别是如果您正在编写小型、易于使用的功能组件。
包含 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
}
但您会误会...前两行包含大量 props
转换。其实应该是
Menu.propTypes = {
userId: PropTypes.number.isRequired,
location: PropTypes.shape({
pathname: PropTypes.string.isRequired
}).isRequired
}
为什么?该片段等价于ui等于:
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
(可能还有其他你不关心的事情)。
希望对您有所帮助。
我想知道在将用第 3 方 HOC 包装的组件上定义 propTypes
的最佳实践是什么,在这种情况下,withRouter()
来自 React-Router
.
据我了解,propTypes
的目的是让您(和其他开发人员)知道组件应该期待什么道具,如果违反,React 会发出警告。
因此,关于位置的 props 已经被 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} />
这种情况下的惯例是什么?
It is my understanding that the point of propTypes is so you (and other developers) know what props a component should expect, and React will give warnings if this is violated.
这是正确的。
What would be the convention in this case?
我认为您不会找到明确的答案。有些人会争辩说,如果你定义一个 propType
你应该定义所有预期的道具类型。其他人会像您一样说,它不会由父组件(不包括 HOC)提供,所以何必呢。还有一类人会告诉你根本不用担心 propTypes
...
就个人而言,我属于第一类或最后一类:
- 如果组件是供其他人使用的,例如通用 ui 组件(例如 TextField、Button 等)或库的界面,那么
propTypes
很有帮助,你应该定义它们。 - 如果组件仅用于特定目的,在单个应用程序中,那么通常根本不用担心它们,因为在传递错误的 props 时,您将花费更多的时间来维护它们而不是调试 (特别是如果您正在编写小型、易于使用的功能组件。
包含 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
}
但您会误会...前两行包含大量 props
转换。其实应该是
Menu.propTypes = {
userId: PropTypes.number.isRequired,
location: PropTypes.shape({
pathname: PropTypes.string.isRequired
}).isRequired
}
为什么?该片段等价于ui等于:
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
(可能还有其他你不关心的事情)。
希望对您有所帮助。