如何定义与用fithrouter包裹的组件的预售



我想知道在将用第三方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(也许还有其他您不在乎的事情(。

希望会有所帮助。

最新更新