3

我想知道在propTypes将用 3rd-party HOC 包装的组件上定义的最佳实践是什么,在这种情况下,withRouter()来自React-Router.

我的理解是,这样做的propTypes目的是让您(和其他开发人员)知道组件应该期望什么 props,如果违反,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} />

在这种情况下,约定是什么?

4

1 回答 1

2

我的理解是 propTypes 的目的是让您(和其他开发人员)知道组件应该期望什么 props,如果违反,React 会发出警告。

这是对的。

在这种情况下,约定是什么?

我不认为你会找到一个明确的答案。有些人会争辩说,如果你定义一个propType,你应该定义所有预期的道具类型。其他人会说,就像您所做的那样,它不会由父组件(不包括 HOC)提供,所以为什么要打扰。还有一类人会告诉你根本不用担心propTypes......

就个人而言,我属于第一类或最后一类:

  • 如果该组件是供其他人使用的,例如普通的 ui 组件(例如 TextField、Button 等)或库的接口,则propTypes很有帮助,您应该将它们全部定义。
  • 如果组件仅用于特定目的,在单个应用程序中,那么通常完全不用担心它们,因为当传递错误的 props 时,你将花费更多的时间来维护它们而不是调试(尤其是如果你编写小型、易于使用的功能组件)。

包含 的routerProps理由是为了保护您免受withRouter将来更改时提供的道具的更改。

因此,假设您要包含propTypesforwithRouter那么我们需要分解它们实际上应该是什么:

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(可能还有其他您不关心的事情)。

希望有帮助。

于 2017-06-25T06:11:30.143 回答