React Typescript - 在路由中传递时如何将类型添加到 location.state
Posted
技术标签:
【中文标题】React Typescript - 在路由中传递时如何将类型添加到 location.state【英文标题】:React Typescript - How add Types to location.state when passed in a Route 【发布时间】:2020-06-06 04:12:38 【问题描述】:当我将 react-router props 发送到 Route 中的组件传递时出现错误,因为我具有传递此组件的特定状态,但错误显示在我的 Route 中。
这是路线代码:
<Route
exact
path='/flipltimeline'
render=props => <FliplTimeline ...props />
在另一个组件中我称之为下面
props.history.push(`/flipltimeline`,
Approval: singleFliplApprovals,
InvestigationID,
Unit: unit,
Cost: cost
);
这是组件的代码。我终于得到了 Typescript 来编译它,但我必须合并 LocationState 和 TimelineState 才能让它工作。但是现在,当我将道具发送到我的 FliplTimeline 组件时,Typescript 会抛出上面的屏幕截图。任何人都知道如何解决这个问题?
history.tsx
import createBrowserHistory from 'history';
let baseNameProd = '';
if (process.env.NODE_ENV !== 'production')
console.log('Looks like we are in development mode!');
baseNameProd = '';
else
baseNameProd = '/flipl';
const customHistory = createBrowserHistory(
basename: baseNameProd
);
export default customHistory;
翻转时间线.tsx
import * as React from 'react';
import History, LocationState from 'history';
interface FliplTimelineLocationState
Approval: any;
InvestigationID: number;
Unit: string;
Cost: number;
interface TimelineState
state: FliplTimelineLocationState;
interface Props
history: History;
location: LocationState & TimelineState;
function FliplTimeline(props: Props)
return (
<ModuleTemplate title='Status Timeline' subtitle=''>
<FliplTimelineJumbotron className='bg-primary-darker shadow-4 line-height-serif-4'>
<div className='grid-row'>
<div className='grid-col-4'>
<span
className='font-mono-2xl text-white'
style=
verticalAlign: 'middle'
>
FLIPL' '
</span>
<span
className='font-mono-xl text-gold'
style=
verticalAlign: 'middle'
>
props.location.state.InvestigationID
</span>
更新:添加了我的 history.tsx 文件,我在其中为 React-Router 创建了自己的历史记录。也在导入语句中添加。
更新:尝试将我的 FliplTimeline 组件更改为具有此界面
import RouteComponentProps from 'react-router-dom'
function FliplTimeline(props: RouteComponentProps )
我收到 2 个错误。第一个是这个,另一个说道具的形状不对。想法?
更新:我终于能够为我的组件获得正确的道具声明。
import RouteComponentProps from 'react-router-dom';
interface FliplTimelineLocationState
Approval: any;
InvestigationID: number;
Unit: string;
Cost: number;
function FliplTimeline(
props: RouteComponentProps<, any, FliplTimelineLocationState | any>
)
【问题讨论】:
【参考方案1】:我能够让它工作。
import RouteComponentProps from 'react-router-dom';
interface FliplTimelineLocationState
Approval: any;
InvestigationID: number;
Unit: string;
Cost: number;
function FliplTimeline(
props: RouteComponentProps<, any, FliplTimelineLocationState | any>
)
【讨论】:
【参考方案2】:使用RouteComponentProps
并为其泛型提供适当的类型。这篇文章涵盖了很多:How to Use React Router in Typescript.
使用带有 TypeScript 的 React Router 几乎需要填写 React Router 所具有的泛型。否则没有足够的上下文来确定所有事物的类型。与我下面的示例进行比较。我使用useHistory
并用我希望可用的类型填充它。这可能是您的FliplTimelineLocationState
,这样history
的state
属性就可以确定为FliplTimelineLocationState
类型。
import React, MouseEventHandler from "react";
import Route, RouteComponentProps, StaticContext, useHistory from "react-router";
import BrowserRouter, Link from "react-router-dom";
interface IMyScreenRouteParams
foo: string;
// You don't have to extend, you could just use StaticContext
interface IMyStaticContext extends StaticContext
bar: string;
interface IHistory
fizz: string;
const Nav = () =>
const history = useHistory<IHistory>();
const clickHanlder: MouseEventHandler = () =>
history.push("/my-screen",
fizz: "you said fizz"
);
;
return (
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/my-screen">My Screen</Link></li>
<li><button onClick=clickHanlder>My Screen with state</button></li>
<li><Link to="/my-screen?q=hello">My Screen with query</Link></li>
<li><Link to="/my-screen/bob">My Screen using match</Link></li>
</ul>
<div>
<button onClick=() => history.goBack()>Back</button>
<button onClick=() => history.push("/")>Home</button>
<button onClick=() => history.goForward()>Forward</button>
</div>
</nav>
);
;
const MyScreen = (
location,
match,
history,
staticContext
: RouteComponentProps<IMyScreenRouteParams, IMyStaticContext, IHistory>) => (
<div>
<section>
<h2>Location</h2>
<p><code>location</code> has <code>IHistory</code> props.</p>
<pre><code>JSON.stringify(location, null, 4)</code></pre>
</section>
<section>
<h2>Match</h2>
<p><code>match</code> has <code>IMyScreenRouteParams</code> props.</p>
<pre><code>JSON.stringify(match, null, 4)</code></pre>
</section>
<section>
<h2>History</h2>
<p><code>history</code> has <code>IHistory</code> props.</p>
<pre><code>JSON.stringify(history, null, 4)</code></pre>
</section>
<section>
<h2>Static Context</h2>
<p><code>staticContext</code> has <code>IMyStaticContext</code> props or whatever static context your router has.</p>
<p>This is for a <a href="https://reacttraining.com/react-router/web/api/StaticRouter/context-object"><code><StaticRouter/></code></a>.</p>
<pre><code>JSON.stringify(staticContext, null, 4)</code></pre>
</section>
</div>
);
const Router = () => (
<BrowserRouter>
<div
style=
display: "flex",
flexDirection: "row"
>
<Nav />
<main>
<Route exact path="/" component=() => (<div>Click something in the <code><nav/></code></div>) />
<Route exact path="/my-screen" component=MyScreen />
<Route exact path="/my-screen/:id" component=MyScreen />
</main>
</div>
</BrowserRouter>
);
export default Router;
【讨论】:
感谢您的评论。我在这个中使用了一个类组件,我知道在这个例子中使用钩子是有区别的。我会尝试使用 RouteComponentProps。以上是关于React Typescript - 在路由中传递时如何将类型添加到 location.state的主要内容,如果未能解决你的问题,请参考以下文章
React/Typescript Route 组件字段类型错误
Typescript & React:在组件之间传递道具与默认道具
TypeScript 和 React:在 props 中传递组件并从函数中返回它
使用 MaterialUI 和 Typescript 在 React 中传递给 onKeyPressed 函数的事件的正确类型是啥?