Skip to content

Commit

Permalink
feat: convert withRouter, server to TS (#1027)
Browse files Browse the repository at this point in the history
* feat: convert withRouter, server to TS

* small naming changes

* minor change
  • Loading branch information
golota60 committed Jan 8, 2023
1 parent 556b3e5 commit a77dfc4
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function Link({

if (childrenIsFunction || activeClassName || activeStyle || activePropName) {
const toLocation = router.createLocation(to);
const active = router.isActive(match, toLocation, { exact });
const active = router.isActive(match!, toLocation, { exact });

if (childrenIsFunction) {
const add = { href, active, onClick: handleClick };
Expand Down
10 changes: 8 additions & 2 deletions src/RouterContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React from 'react';

// TODO: types
export default React.createContext<any>(null);
import { Match, Router } from './typeUtils';

export interface RouterContextState<TContext = any> {
match: Match<TContext> | null;
router: Router;
}

export default React.createContext<RouterContextState>(null as any);
16 changes: 16 additions & 0 deletions src/additional.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,21 @@ declare global {
}
}

declare module '@restart/context/mapContextToProps' {
export default function mapContextToProps<
TComponent,
TContext,
TContextProps,
TOwnProps,
>(
data: {
consumers: TContext;
mapToProps: (context: TContext) => TContext;
displayName: string;
},
Component: TComponent,
): ContextInjectedComponent<TComponent, TContextProps, TOwnProps>;
}

// Force this to be a module
export {};
8 changes: 2 additions & 6 deletions src/createBaseRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { Store } from 'redux';
import warning from 'tiny-warning';

import ActionTypes from './ActionTypes';
import RouterContext from './RouterContext';
import RouterContext, { RouterContextState } from './RouterContext';
import StaticContainer from './StaticContainer';
import createRender from './createRender';
import createStoreRouterObject from './createStoreRouterObject';
import resolveRenderArgs from './resolveRenderArgs';
import {
ConnectedRouterProps,
CreateRenderOptions,
Match,
MatchBase,
RenderArgs,
Resolver,
Expand All @@ -35,10 +34,7 @@ interface BaseRouterState {
matchContext: any;
resolver: Resolver;
iteration: number;
routerContext: {
match: Match | null;
router: Router;
};
routerContext: RouterContextState;
element: React.ReactElement | null;
}

Expand Down
12 changes: 9 additions & 3 deletions src/createFarceStore.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { Protocol } from 'farce';
import { FarceStoreExtension, Protocol } from 'farce';
import FarceActions from 'farce/Actions';
import createHistoryEnhancer, {
HistoryEnhancerOptions,
} from 'farce/createHistoryEnhancer';
import queryMiddleware from 'farce/queryMiddleware';
import { Middleware, combineReducers, compose, createStore } from 'redux';
import {
Middleware,
StoreEnhancer,
combineReducers,
compose,
createStore,
} from 'redux';

import Matcher from './Matcher';
import createMatchEnhancer from './createMatchEnhancer';
Expand Down Expand Up @@ -35,7 +41,7 @@ function createFarceStore({
...historyOptions,
protocol: historyProtocol,
middlewares: historyMiddlewares || [queryMiddleware],
}) as any,
}) as StoreEnhancer<{ farce: FarceStoreExtension }>,
createMatchEnhancer(new Matcher(routeConfig, matcherOptions)),
),
);
Expand Down
27 changes: 21 additions & 6 deletions src/server.js → src/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ import createFarceStore from './createFarceStore';
import createRender from './createRender';
import getStoreRenderArgs from './getStoreRenderArgs';
import defaultResolver from './resolver';
import { RenderArgs } from './typeUtils';

const propTypes = {
renderArgs: PropTypes.shape({
router: routerShape.isRequired,
}).isRequired,
router: routerShape,
}),
children: PropTypes.node,
};

function RouterProvider({ renderArgs, children }) {
interface RouterProviderProps {
renderArgs: RenderArgs;
children: React.ReactNode;
}

function RouterProvider({ renderArgs, children }: RouterProviderProps) {
return (
<RouterContext.Provider
value={useMemo(
Expand All @@ -37,6 +43,12 @@ RouterProvider.propTypes = propTypes;

export { RouterProvider };

interface FarceResult {
status: number;
element?: any;
redirect?: any;
}

export async function getFarceResult({
url,
historyMiddlewares,
Expand All @@ -52,15 +64,15 @@ export async function getFarceResult({
renderReady,
renderError,
}),
}) {
}): Promise<FarceResult> {
const store = createFarceStore({
historyProtocol: new ServerProtocol(url),
historyMiddlewares,
historyOptions,
routeConfig,
});

let renderArgs;
let renderArgs: RenderArgs;

try {
renderArgs = await getStoreRenderArgs({
Expand Down Expand Up @@ -88,7 +100,10 @@ export async function getFarceResult({
}

return {
status: renderArgs.error ? renderArgs.error.status : 200,
status:
'error' in renderArgs && renderArgs.error
? renderArgs.error.status
: 200,
element: (
<RouterProvider renderArgs={renderArgs}>
{render(renderArgs)}
Expand Down
4 changes: 2 additions & 2 deletions src/useLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { Location } from 'farce';

import useMatch from './useMatch';

export default function useLocation(): Location {
return useMatch().location;
export default function useLocation(): Location | undefined {
return useMatch()?.location;
}
2 changes: 1 addition & 1 deletion src/useMatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { Match } from './typeUtils';
import useRouter from './useRouter';

/** Returns the current route Match */
export default function useMatch<TContext = any>(): Match<TContext> {
export default function useMatch<TContext = any>(): Match<TContext> | null {
return useRouter().match;
}
4 changes: 2 additions & 2 deletions src/useParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { Params } from './typeUtils';
import useMatch from './useMatch';

/** Returns the current route params */
export default function useParams(): Params {
return useMatch().params;
export default function useParams(): Params | undefined {
return useMatch()?.params;
}
9 changes: 5 additions & 4 deletions src/useRouter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useContext } from 'react';

import RouterContext from './RouterContext';
import { RouterState } from './typeUtils';
import RouterContext, { RouterContextState } from './RouterContext';

/**
* Returns the Router and current route match from context
*/
export default function useRouter<TContext = any>(): RouterState<TContext> {
return useContext<RouterState<TContext>>(RouterContext);
export default function useRouter<
TContext = any,
>(): RouterContextState<TContext> {
return useContext<RouterContextState<TContext>>(RouterContext);
}
4 changes: 2 additions & 2 deletions src/withRouter.js → src/withRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import mapContextToProps from '@restart/context/mapContextToProps';

import RouterContext from './RouterContext';

export default function withRouter(Component) {
export default function withRouter(Component: React.ComponentType<any>) {
return mapContextToProps(
{
consumers: RouterContext,
mapToProps: (context) => context,
mapToProps: (context: typeof RouterContext) => context,
displayName: `withRouter(${Component.displayName || Component.name})`,
},
Component,
Expand Down

0 comments on commit a77dfc4

Please sign in to comment.