Skip to content

Commit 5811466

Browse files
Add additional JSDoc comments to commonly used APIs for better API reference and in-editor documentation. (#12975)
Co-authored-by: Matt Brophy <[email protected]>
1 parent 2058db1 commit 5811466

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

packages/react-router/lib/router/utils.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,28 @@ export type Submission =
116116
* this as a private implementation detail in case they diverge in the future.
117117
*/
118118
interface DataFunctionArgs<Context> {
119+
/** A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read headers (like cookies, and {@link https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams URLSearchParams} from the request. */
119120
request: Request;
121+
/**
122+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
123+
* @example
124+
* // app/routes.ts
125+
* route("teams/:teamId", "./team.tsx"),
126+
*
127+
* // app/team.tsx
128+
* export function loader({
129+
* params,
130+
* }: Route.LoaderArgs) {
131+
* params.teamId;
132+
* // ^ string
133+
* }
134+
**/
120135
params: Params;
136+
/**
137+
* This is the context passed in to your server adapter's getLoadContext() function.
138+
* It's a way to bridge the gap between the adapter's request/response API with your React Router app.
139+
* It is only applicable if you are using a custom server adapter.
140+
*/
121141
context?: Context;
122142
}
123143

@@ -166,18 +186,56 @@ export interface ActionFunction<Context = any> {
166186
* Arguments passed to shouldRevalidate function
167187
*/
168188
export interface ShouldRevalidateFunctionArgs {
189+
/** This is the url the navigation started from. You can compare it with `nextUrl` to decide if you need to revalidate this route's data. */
169190
currentUrl: URL;
191+
/** These are the {@link https://reactrouter.com/start/framework/routing#dynamic-segments dynamic route params} from the URL that can be compared to the `nextParams` to decide if you need to reload or not. Perhaps you're using only a partial piece of the param for data loading, you don't need to revalidate if a superfluous part of the param changed. */
170192
currentParams: AgnosticDataRouteMatch["params"];
193+
/** In the case of navigation, this the URL the user is requesting. Some revalidations are not navigation, so it will simply be the same as currentUrl. */
171194
nextUrl: URL;
195+
/** In the case of navigation, these are the {@link https://reactrouter.com/start/framework/routing#dynamic-segments dynamic route params} from the next location the user is requesting. Some revalidations are not navigation, so it will simply be the same as currentParams. */
172196
nextParams: AgnosticDataRouteMatch["params"];
197+
/** The method (probably `"GET"` or `"POST"`) used in the form submission that triggered the revalidation. */
173198
formMethod?: Submission["formMethod"];
199+
/** The form action (`<Form action="/somewhere">`) that triggered the revalidation. */
174200
formAction?: Submission["formAction"];
201+
/** The form encType (`<Form encType="application/x-www-form-urlencoded">) used in the form submission that triggered the revalidation*/
175202
formEncType?: Submission["formEncType"];
203+
/** The form submission data when the form's encType is `text/plain` */
176204
text?: Submission["text"];
205+
/** The form submission data when the form's encType is `application/x-www-form-urlencoded` or `multipart/form-data` */
177206
formData?: Submission["formData"];
207+
/** The form submission data when the form's encType is `application/json` */
178208
json?: Submission["json"];
209+
/** The status code of the action response */
179210
actionStatus?: number;
211+
/**
212+
* When a submission causes the revalidation this will be the result of the action—either action data or an error if the action failed. It's common to include some information in the action result to instruct shouldRevalidate to revalidate or not.
213+
*
214+
* @example
215+
* export async function action() {
216+
* await saveSomeStuff();
217+
* return { ok: true };
218+
* }
219+
*
220+
* export function shouldRevalidate({
221+
* actionResult,
222+
* }) {
223+
* if (actionResult?.ok) {
224+
* return false;
225+
* }
226+
* return true;
227+
* }
228+
*/
180229
actionResult?: any;
230+
/**
231+
* By default, React Router doesn't call every loader all the time. There are reliable optimizations it can make by default. For example, only loaders with changing params are called. Consider navigating from the following URL to the one below it:
232+
*
233+
* /projects/123/tasks/abc
234+
* /projects/123/tasks/def
235+
* React Router will only call the loader for tasks/def because the param for projects/123 didn't change.
236+
*
237+
* It's safest to always return defaultShouldRevalidate after you've done your specific optimizations that return false, otherwise your UI might get out of sync with your data on the server.
238+
*/
181239
defaultShouldRevalidate: boolean;
182240
}
183241

@@ -556,8 +614,13 @@ export function matchRoutesImpl<
556614
export interface UIMatch<Data = unknown, Handle = unknown> {
557615
id: string;
558616
pathname: string;
617+
/**
618+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the matched route.
619+
**/
559620
params: AgnosticRouteMatch["params"];
621+
/** The return value from the matched route's loader or clientLoader */
560622
data: Data;
623+
/** The {@link https://reactrouter.com/start/framework/route-module#handle handle object} exported from the matched route module */
561624
handle: Handle;
562625
}
563626

packages/react-router/lib/types/route-module.ts

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ type MetaMatches<T extends RouteInfo[]> =
5151
: Array<MetaMatch<RouteInfo> | undefined>;
5252

5353
export type CreateMetaArgs<T extends RouteInfo> = {
54+
/** This is the current router `Location` object. This is useful for generating tags for routes at specific paths or query parameters. */
5455
location: Location;
56+
/** {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route. */
5557
params: T["params"];
58+
/** The return value for this route's server loader function */
5659
data: T["loaderData"];
60+
/** Thrown errors that trigger error boundaries will be passed to the meta function. This is useful for generating metadata for error pages. */
5761
error?: unknown;
62+
/** An array of the current {@link https://api.reactrouter.com/v7/interfaces/react_router.UIMatch.html route matches}, including parent route matches. */
5863
matches: MetaMatches<[...T["parents"], T]>;
5964
};
6065
export type MetaDescriptors = MetaDescriptor[];
@@ -109,11 +114,52 @@ type _CreateActionData<ServerActionData, ClientActionData> = Awaited<
109114
>
110115

111116
type ClientDataFunctionArgs<T extends RouteInfo> = {
117+
/**
118+
* A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read the URL, the method, the "content-type" header, and the request body from the request.
119+
*
120+
* @note Because client data functions are called before a network request is made, the Request object does not include the headers which the browser automatically adds. React Router infers the "content-type" header from the enc-type of the form that performed the submission.
121+
**/
112122
request: Request;
123+
/**
124+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
125+
* @example
126+
* // app/routes.ts
127+
* route("teams/:teamId", "./team.tsx"),
128+
*
129+
* // app/team.tsx
130+
* export function clientLoader({
131+
* params,
132+
* }: Route.ClientLoaderArgs) {
133+
* params.teamId;
134+
* // ^ string
135+
* }
136+
**/
113137
params: T["params"];
114138
};
115139

116-
type ServerDataFunctionArgs<T extends RouteInfo> = ClientDataFunctionArgs<T> & {
140+
type ServerDataFunctionArgs<T extends RouteInfo> = {
141+
/** A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read the url, method, headers (such as cookies), and request body from the request. */
142+
request: Request;
143+
/**
144+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
145+
* @example
146+
* // app/routes.ts
147+
* route("teams/:teamId", "./team.tsx"),
148+
*
149+
* // app/team.tsx
150+
* export function loader({
151+
* params,
152+
* }: Route.LoaderArgs) {
153+
* params.teamId;
154+
* // ^ string
155+
* }
156+
**/
157+
params: T["params"];
158+
/**
159+
* This is the context passed in to your server adapter's getLoadContext() function.
160+
* It's a way to bridge the gap between the adapter's request/response API with your React Router app.
161+
* It is only applicable if you are using a custom server adapter.
162+
*/
117163
context: AppLoadContext;
118164
};
119165

@@ -122,6 +168,7 @@ export type CreateServerLoaderArgs<T extends RouteInfo> =
122168

123169
export type CreateClientLoaderArgs<T extends RouteInfo> =
124170
ClientDataFunctionArgs<T> & {
171+
/** This is an asynchronous function to get the data from the server loader for this route. On client-side navigations, this will make a {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API fetch} call to the React Router server loader. If you opt-into running your clientLoader on hydration, then this function will return the data that was already loaded on the server (via Promise.resolve). */
125172
serverLoader: () => Promise<ServerDataFrom<T["module"]["loader"]>>;
126173
};
127174

@@ -130,6 +177,7 @@ export type CreateServerActionArgs<T extends RouteInfo> =
130177

131178
export type CreateClientActionArgs<T extends RouteInfo> =
132179
ClientDataFunctionArgs<T> & {
180+
/** This is an asynchronous function that makes the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API fetch} call to the React Router server action for this route. */
133181
serverAction: () => Promise<ServerDataFrom<T["module"]["action"]>>;
134182
};
135183

@@ -154,13 +202,44 @@ type Matches<T extends RouteInfo[]> =
154202
: Array<Match<RouteInfo> | undefined>;
155203

156204
export type CreateComponentProps<T extends RouteInfo> = {
205+
/**
206+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
207+
* @example
208+
* // app/routes.ts
209+
* route("teams/:teamId", "./team.tsx"),
210+
*
211+
* // app/team.tsx
212+
* export default function Component({
213+
* params,
214+
* }: Route.ComponentProps) {
215+
* params.teamId;
216+
* // ^ string
217+
* }
218+
**/
157219
params: T["params"];
220+
/** The data returned from the `loader` or `clientLoader` */
158221
loaderData: T["loaderData"];
222+
/** The data returned from the `action` or `clientAction` following an action submission. */
159223
actionData?: T["actionData"];
224+
/** An array of the current {@link https://api.reactrouter.com/v7/interfaces/react_router.UIMatch.html route matches}, including parent route matches. */
160225
matches: Matches<[...T["parents"], T]>;
161226
};
162227

163228
export type CreateErrorBoundaryProps<T extends RouteInfo> = {
229+
/**
230+
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
231+
* @example
232+
* // app/routes.ts
233+
* route("teams/:teamId", "./team.tsx"),
234+
*
235+
* // app/team.tsx
236+
* export function ErrorBoundary({
237+
* params,
238+
* }: Route.ErrorBoundaryProps) {
239+
* params.teamId;
240+
* // ^ string
241+
* }
242+
**/
164243
params: T["params"];
165244
error: unknown;
166245
loaderData?: T["loaderData"];

0 commit comments

Comments
 (0)