Fixes #31316: Add RouterContext type, update react-router to 5.0 (#35144)

Includes test example for RouterContext
This commit is contained in:
Nick Hehr
2019-05-07 15:26:09 -07:00
committed by Jesse Trinity
parent c1e2a6529e
commit d4b1e4ab88
3 changed files with 119 additions and 2 deletions
+4 -1
View File
@@ -1,4 +1,4 @@
// Type definitions for React Router 4.4
// Type definitions for React Router 5.0
// Project: https://github.com/ReactTraining/react-router
// Definitions by: Sergey Buturlakin <https://github.com/sergey-buturlakin>
// Yuichi Murata <https://github.com/mrk21>
@@ -21,6 +21,7 @@
// Ben Smith <https://github.com/8enSmith>
// Wesley Tsai <https://github.com/wezleytsai>
// Sebastian Silbermann <https://github.com/eps1lon>
// Nicholas Hehr <https://github.com/HipsterBrown>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
@@ -137,3 +138,5 @@ export function generatePath(pattern: string, params?: { [paramName: string]: st
// you will see a bunch of errors from TypeScript. The current workaround is to use withRouter() as a function call
// on a separate line instead of as a decorator.
export function withRouter<P extends RouteComponentProps<any>>(component: React.ComponentType<P>): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>>>;
export const __RouterContext: React.Context<RouteComponentProps>;
+113
View File
@@ -0,0 +1,113 @@
import * as React from "react";
import { __RouterContext as RouterContext } from "react-router";
import {
BrowserRouter as Router,
Link,
Route,
RouteComponentProps
} from "react-router-dom";
const App = () => (
<Router>
<div>
<ul>
<li>
<Link to="/signup">SignUp Page</Link>
</li>
</ul>
<Route path="/signup" component={Signup} />
<Route path="/welcome" component={Welcome} />
</div>
</Router>
);
const Welcome: React.FC<RouteComponentProps> = () => (
<h1>Welcome to this site!</h1>
);
const Signup: React.FC<RouteComponentProps> = () => (
<div>
<h1>Signup for this site</h1>
<p>Just a few steps to complete this process.</p>
<Link to="/signup/username">Get Started</Link>
<MultiStepSignup />
</div>
);
const steps = ["username", "password", "basic_info"];
const MultiStepSignup: React.FC = () => {
const { history, location, match } = React.useContext(RouterContext);
const { currentStep, currentStepIndex, isLastStep } = React.useMemo(() => {
const currentStep = location.pathname.split("/").pop() || "";
const currentStepIndex = steps.indexOf(currentStep);
return {
currentStep,
currentStepIndex,
isLastStep: currentStepIndex === steps.length - 1
};
}, [location.pathname]);
const handleNextStep = React.useCallback(
event => {
event.preventDefault();
if (isLastStep) {
// submit data to api here
history.push("/welcome");
} else {
// go to next step
const nextStep = steps[currentStepIndex + 1];
history.push(`/signup/${nextStep}`);
}
},
[currentStep]
);
return (
<form onSubmit={handleNextStep}>
<Route path={`${match.path}/username`} component={UsernameStep} />
<Route path={`${match.path}/password`} component={PasswordStep} />
<Route
path={`${match.path}/basic_info`}
component={BasicInfoStep}
/>
<button type="submit">
{isLastStep ? "Complete" : "Next Step"}
</button>
</form>
);
};
const UsernameStep: React.FC<RouteComponentProps> = () => (
<div>
<h2>Pick out a fun username!</h2>
<label htmlFor="username">
Username: <input type="text" id="usernanme" name="username" />
</label>
</div>
);
const PasswordStep: React.FC<RouteComponentProps> = () => (
<div>
<h2>Pick out a secure password!</h2>
<label htmlFor="password">
Username: <input type="password" id="password" name="password" />
</label>
</div>
);
const BasicInfoStep: React.FC<RouteComponentProps> = () => (
<div>
<h2>Just some basic information to finish up.</h2>
<label htmlFor="name">
Username: <input type="text" id="name" name="name" />
</label>
<label htmlFor="email">
Username: <input type="email" id="email" name="email" />
</label>
</div>
);
+2 -1
View File
@@ -39,6 +39,7 @@
"test/MemoryRouter.tsx",
"test/Switch.tsx",
"test/InheritingRoute.tsx",
"test/WithRouter.tsx"
"test/WithRouter.tsx",
"test/RouterContext.tsx"
]
}