如何为包含withRouter的组件定义propTypes?

时间:2017-06-25 04:17:51

标签: javascript reactjs react-router higher-order-components

我想知道在将使用第三方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} />

在这种情况下会有什么约定?

1 个答案:

答案 0 :(得分:2)

  

我的理解是propTypes的重点在于你(和其他开发人员)知道组件应该期望什么道具,如果违反了,React会发出警告。

这是正确的。

  

在这种情况下会有什么约定?

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

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

  • 如果组件供其他人使用,例如常用的ui组件(例如TextField,Button等)或库的界面,则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。  ...routerPropsrest parameter,因此它会获得props的所有其他值,在这种情况下,location(也许还有其他你不关心的事情)

希望有所帮助。