要设置上下文,我在lesson 12 of react-router-tutorial,但是随着我的跟进,我实际上在使用TypeScript进行操作。在本教程的这一点上,在几个React组件中有一个名为Repos
export class Repos extends React.Component<ReposProps, {}> { ... }
是在Router
<Router history={browserHistory}>
{/* ... */}
<Route path="/repos" component={Repos}>{/* ... */}</Route>
{/* ... */}
</Router>
Repos
中的某个地方是一个方法,它从HTML表单中获取一些参数并构造一个新路径来引导浏览器:
handleSubmit(event: React.FormEvent) {
/* ... (define userName and repo vars) */
const path = `/repos/${userName}/${repo}`
this.context.router.push(path);
}
我的问题是最后一行context
和router
的类型是什么?
在the React documentation on Contexts中,我逐渐明白上下文通常在每个元素中定义。这里的一个好主意似乎是在context
中使用从react-router's TypeScript type definitions中定义的某个接口扩展的接口来定义Repos
interface ReposContext extends Something /* ??? */ { }
此处,Something
会将router
定义为具有push
方法的某种类型。
API并不是说Router
有方法push
,尽管Glossary确实如此,这令人困惑。无论如何,DefinitelyTyped上的类型定义没有在push
下定义Router
方法(虽然我不相信它们是完美的,但这个遗漏对我来说似乎并不是偶然的)
相同的API会指出RouterContext
提及context.router
- context.router
确定push()
以及其他一些方法。
然后我注意到在历史中。在反应路由器的类型定义中,接口History
具有所有相同的方法(加上几个
也许这个界面越来越近了。它并没有像我想要的那样扩展任何东西(也许这是改进路由器改进的空间),但它有我需要的东西。
interface ContextRouter extends History { }
interface ReposContext {
router: ContextRouter
}
我仍然怀疑,因为虽然ContextRouter
延伸History
答案 0 :(得分:2)
我使用ReactRouter.RouterOnContext:
context: {
router: ReactRouter.RouterOnContext
}
答案 1 :(得分:0)
我已经通过深入反应路由器代码来解决这个问题。通过弄清楚如何创建路由器,我最终在match.js中发现路由器实际上是通过将历史传递给createRouterObject来创建的,createRouterObject只创建一个具有与历史相同属性的对象以及一对其他财产。
路由器的类型确实扩展了历史记录。