Skip to content

Commit aa40b7c

Browse files
committed
Updated React docs
1 parent b831898 commit aa40b7c

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

apps/web/app/hoc/auth-button.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { withAuth } from "./auth";
2+
3+
const AuthButton = ({ isLoggedIn }: { isLoggedIn: boolean }) => {
4+
return (
5+
<div>{isLoggedIn ? <button>Logout</button> : <button>Login</button>}</div>
6+
);
7+
};
8+
9+
export default withAuth(AuthButton);

apps/web/app/hoc/auth.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { ComponentProps } from "react";
2+
3+
const useIsLoggedIn = () => {
4+
return true;
5+
};
6+
7+
export const withAuth = <T extends ComponentProps<"div">>(
8+
Component: React.ComponentType<T & { isLoggedIn: boolean }>
9+
) => {
10+
const WithAuth = (props: T) => {
11+
const isLoggedIn = useIsLoggedIn();
12+
return <Component {...props} isLoggedIn={isLoggedIn} />;
13+
};
14+
type WithoutAuthProps = Omit<T, "isLoggedIn">;
15+
return WithAuth as React.ComponentType<WithoutAuthProps>;
16+
};

apps/web/app/hoc/page.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import AuthButton from "./auth-button";
2+
3+
export default function HocPage() {
4+
return (
5+
<div>
6+
HocPage
7+
<AuthButton />
8+
</div>
9+
);
10+
}

docs/docs/guide/react.mdx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,14 @@ import { useIsLoggedIn } from "../hooks/use-is-logged-in";
231231
import type { ComponentProps } from "react";
232232

233233
export const withAuth = <T extends ComponentProps<"div">>(
234-
Component: React.ComponentType<T>
234+
Component: React.ComponentType<T & { isLoggedIn: boolean }>
235235
) => {
236236
const WithAuth = (props: T) => {
237237
const isLoggedIn = useIsLoggedIn();
238238
return <Component {...props} isLoggedIn={isLoggedIn} />;
239239
};
240-
return WithAuth as React.ComponentType<T>;
240+
type WithoutAuthProps = Omit<T, "isLoggedIn">;
241+
return WithAuth as React.ComponentType<WithoutAuthProps>;
241242
};
242243
```
243244

@@ -385,6 +386,11 @@ export const serverFunction = async (formData: FormData) => {
385386

386387
As you can see, we just need to make sure that every input field has a `name` attribute so that the server function can extract the value of the input field from the form data.
387388

389+
<Callout type="info" title="Good to know">
390+
For more information on using server functions, please refer to the [Updating
391+
Data](../guide/updating-data.mdx) guide.
392+
</Callout>
393+
388394
### Input validation
389395

390396
Another common case to use controlled inputs is to validate the input values before sending data to the server. Here's some things you should consider before turning your input fields into controlled components.
@@ -662,6 +668,12 @@ Or we can have `Tabs` component with custom styling like for the tabs list and t
662668

663669
With compound pattern, we have a clear separation of concerns and more flexibility.
664670

671+
<Callout type="info" title="Rule of thumb">
672+
Always aim to keep the component simple with minimum responsibility. Use the
673+
compound pattern to further break down the component into smaller components
674+
that are responsible for a single responsibility.
675+
</Callout>
676+
665677
## Ground Rules
666678

667679
| | Action |

0 commit comments

Comments
 (0)