feat(link): use mounted hook applied to avoid hydratation mismatches

This commit is contained in:
Junior Garcia 2022-12-26 23:09:25 -03:00
parent 1b49d4af09
commit b321322b6a
5 changed files with 34 additions and 13 deletions

View File

@ -41,6 +41,7 @@
"@nextui-org/shared-css": "workspace:*",
"@nextui-org/shared-utils": "workspace:*",
"@nextui-org/system": "workspace:*",
"@nextui-org/use-is-mounted": "workspace:*",
"@react-aria/link": "^3.3.4",
"@react-aria/utils": "^3.14.0",
"@react-aria/focus": "^3.9.0"

View File

@ -3,8 +3,8 @@ import type {AriaLinkProps} from "@react-types/link";
import {useMemo} from "react";
import {useFocusRing} from "@react-aria/focus";
import {HTMLNextUIProps, CSS, getTokenValue} from "@nextui-org/system";
import {isNormalColor} from "@nextui-org//shared-utils";
import {isNormalColor} from "@nextui-org/shared-utils";
import {useIsMounted} from "@nextui-org/use-is-mounted";
export interface Props extends HTMLNextUIProps<"a"> {
/**
* The link's color.
@ -46,13 +46,17 @@ export function useLink(props: UseLinkProps) {
const {isFocusVisible, focusProps} = useFocusRing({autoFocus});
const [, isMounted] = useIsMounted({rerender: true});
const linkCss = useMemo(() => {
const isNormal = isNormalColor(color as string);
const linkColor = isNormal ? `$${color}` : color;
const backgroundColor = isNormal
? `${linkColor}Light`
: getTokenValue("colors", color as string, 0.2);
: isMounted
? getTokenValue("colors", color as string, 0.2)
: "transparent";
if (block) {
return {
@ -66,7 +70,7 @@ export function useLink(props: UseLinkProps) {
}
return {color: linkColor};
}, [color, block]);
}, [color, block, isMounted]);
return {linkCss, focusProps, isExternal, animated, isFocusVisible, ...otherProps};
}

View File

@ -4,9 +4,9 @@ import {renderToStaticMarkup} from "react-dom/server";
import {useIsMounted} from "../src";
function Example() {
const isMounted = useIsMounted();
const [, isMounted] = useIsMounted({rerender: true});
return <p>{isMounted() ? "mounted" : "not mounted"}</p>;
return <p>{isMounted ? "mounted" : "not mounted"}</p>;
}
describe("useIsMounted", () => {

View File

@ -1,20 +1,34 @@
import {useCallback, useEffect, useRef} from "react";
import {useCallback, useEffect, useRef, useState} from "react";
export function useIsMounted() {
const isMounted = useRef(false);
export type UseIsMountedProps = {
rerender?: boolean;
};
export function useIsMounted(props: UseIsMountedProps = {}) {
const {rerender = false} = props;
const isMountedRef = useRef(false);
const [isMounted, setIsMounted] = useState(false);
// Update the ref when the component mounts
useEffect(() => {
isMounted.current = true;
isMountedRef.current = true;
if (rerender) {
setIsMounted(true);
}
// Update the ref when the component unmounts
return () => {
isMounted.current = false;
isMountedRef.current = false;
if (rerender) {
setIsMounted(false);
}
};
}, []);
}, [rerender]);
// Return a callback that returns the value of the ref
return useCallback(() => isMounted.current, []);
return [useCallback(() => isMountedRef.current, []), isMounted];
}
export type UseIsMountedReturn = ReturnType<typeof useIsMounted>;

2
pnpm-lock.yaml generated
View File

@ -639,6 +639,7 @@ importers:
'@nextui-org/spacer': workspace:*
'@nextui-org/system': workspace:*
'@nextui-org/text': workspace:*
'@nextui-org/use-is-mounted': workspace:*
'@react-aria/focus': ^3.9.0
'@react-aria/link': ^3.3.4
'@react-aria/utils': ^3.14.0
@ -650,6 +651,7 @@ importers:
'@nextui-org/shared-css': link:../../utilities/shared-css
'@nextui-org/shared-utils': link:../../utilities/shared-utils
'@nextui-org/system': link:../../core/system
'@nextui-org/use-is-mounted': link:../../hooks/use-is-mounted
'@react-aria/focus': 3.9.0_react@17.0.2
'@react-aria/link': 3.3.4_react@17.0.2
'@react-aria/utils': 3.14.0_react@17.0.2