1+ import * as React from 'react' ;
2+ import Router , { initParams , initResult } from './router' ;
3+ import { Context } from 'router-async' ;
4+
5+ export default class BrowserRouter extends Router {
6+ private history : any ;
7+ private unlistenHistroy : any ;
8+ constructor ( props ) {
9+ super ( props ) ;
10+ this . history = props . history ;
11+ }
12+ static async init ( opts : initParams ) : Promise < initResult > {
13+ const result = await super . init ( opts ) ;
14+ return {
15+ ...result ,
16+ Router : BrowserRouter
17+ } ;
18+ }
19+ static childContextTypes = {
20+ router : React . PropTypes . object
21+ } ;
22+ getChildContext ( ) {
23+ return {
24+ router : this
25+ } ;
26+ }
27+ async navigate ( path , ctx = new Context ( ) ) {
28+ try {
29+ const { redirect } = await this . router . match ( { path, ctx } ) ;
30+ if ( redirect ) {
31+ this . history . push ( redirect ) ;
32+ } else {
33+ this . history . push ( path ) ;
34+ }
35+ } catch ( error ) {
36+ this . history . push ( path ) ;
37+ if ( ! this . props . errorHandler ) {
38+ console . error ( 'Match Error' , path , error ) ;
39+ throw error ;
40+ }
41+ }
42+ }
43+ // TODO: maybe we need to make this history methods works through navigate?
44+ goBack ( ) {
45+ this . history . goBack ( ) ;
46+ }
47+ goForward ( ) {
48+ this . history . goForward ( ) ;
49+ }
50+ go ( n ) {
51+ this . history . go ( n ) ;
52+ }
53+ private _locationChanged = async ( { pathname } ) => {
54+ try {
55+ const { path, location, route, status, params, redirect, result, ctx } = await this . router . run ( { path : pathname } ) ;
56+ const props = {
57+ router : {
58+ path,
59+ location,
60+ route,
61+ status,
62+ params,
63+ redirect,
64+ ctx
65+ }
66+ } ;
67+ const renderCallback = Router . makeCallback ( this . router , { path, route, status, params, redirect, result, ctx } ) ;
68+ this . changeComponent ( { Component : result , componentProps : props , path, location, renderCallback } ) ;
69+ } catch ( error ) {
70+ if ( this . props . errorHandler ) {
71+ this . props . errorHandler ( error , this ) ;
72+ } else {
73+ console . error ( 'Resolve Error' , location , error ) ;
74+ throw error ;
75+ }
76+ }
77+ } ;
78+ componentDidMount ( ) {
79+ this . unlistenHistroy = this . history . listen ( this . _locationChanged )
80+ }
81+ componentWillUnmount ( ) {
82+ this . unlistenHistroy ( ) ;
83+ }
84+ }
0 commit comments