react-router 中 location.state 的类型或接口

Posted

技术标签:

【中文标题】react-router 中 location.state 的类型或接口【英文标题】:Type or interface for location.state in react-router 【发布时间】:2020-06-20 12:36:03 【问题描述】:

在一个组件中,有一个 <Link>(来自 react-router-dom)在 state 属性中传递一个对象。

另一个名为ReceiverComponent 的组件正在正确接收该对象。但是,下面的代码抱怨消息:

类型“PoorMansUnknown”不可分配给类型“locationStateProps”。 类型“未定义”不可分配给类型 'locationStateProps'.ts(2322)

type locationStateProps = 
  name: string;


function ReceiverComponent() 
  const location = useLocation();
  const myState: locationStateProps = location.state;
  return (
    <div>
      myState.name
    </div>
  );

我需要以某种方式为状态提供一种类型,而不会出现此错误。如何进行?

【问题讨论】:

state 可以未定义,因此会出现错误。如果您绝对确定它总是有一个值,您可以使用非空断言运算符:const myState: locationStateProps = location.state!; 我不知道非空断言运算符。谢谢。 考虑将变量输入为const myState: locationStateProps | undefined = ...,然后输入myState?.name 或类似的东西,以防状态未定义 好的,这很有帮助。到目前为止,我一直在使用 jsx 进行开发,最近更改为 typescript 并习惯了它。所有的信息都是有帮助的。谢谢。 【参考方案1】:

在 Github 上有一个关于这个问题的 thread。

我实现了线程中提到的这个解决方案并且它有效。

interface Props extends RouteComponentProps<
   myParamProp?: string , // props.match.params.myParamProp
  any, // history
   myStateProp?: string , // props.location.state.myStateProp
> 
  myNormalProp: boolean;

【讨论】:

【参考方案2】:

您还可以构建自己的状态接口并将其转换为:

interface CustomState 
  ...


const location = useLocation()
const state = location.state as CustomState

【讨论】:

【参考方案3】:

对于可能最终出现在这里的其他人......我正在使用 React Router v6,据我所知,它不再导出 RouteComponentProps(我安装了 @types/react-router 和 @types/react-router -dom - 我在DefinitelyTyped 文件中看到了类型定义,但没有从react-router-dom 导出)。

所以,Location 的输入方式,我发现自己无法以安抚 Typescript 的方式扩展它。不过……

我不推荐 as 强制转换,因为它会降低 TypeScript 的效率。好消息!您可以使用 is 而不是 as 来向 TypeScript 证明给定元素确实是您所说的那样。例如:

type LocationStateProps = 
  name: string;


function ReceiverComponent() 
  const location = useLocation();
  const myState = location.state;

  // note that you are defining the return type of this function using `is`
  const hasNameProps = (state: object | null | LocationStateProps): state is LocationStateProps => 
    // you use `as` here, but only so typescript doesn't yell at you while you access the property
    // specifically to test if it is there
    return (state as LocationStateProps).name !== undefined;
  


  return (
    <div>
      /**
       * Now you can check to see if the prop exists. If it does, us it confidently, and TypeScript won't
       * complain! But you're able to provide a fallback in case the value is, for some reason, not there.
       * If you as-cast, you lose that opportunity. It's a little verbose, but it preserves the benefit of
       * TypeScript... Type safety!
       */
      hasNameProps(myState) ? myState.name : "No Name"
    </div>
  );

【讨论】:

【参考方案4】:

对我有用

   interface locationStateProps 
  from:  isEditing: string 

const NewPublication: React.FC<NewPublicationProps> = () => 
  const navigate = useNavigate();

  let location = useLocation();
  const myState: locationStateProps = location.state as locationStateProps;

【讨论】:

写出完美的代码格式加上大括号。 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于react-router 中 location.state 的类型或接口的主要内容,如果未能解决你的问题,请参考以下文章

[react-router] React-Router怎么获取历史对象?

从 URL 中删除 '%20' - React-Router

在 React-router 中没有带链接的 href

react-router 4.0踩到的坑

如何在 react-router 中使用普通的锚链接

[react-router] React-Router 3和React-Router 4有什么变化?添加了什么好的特性?