mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-16 20:49:23 +00:00
refactor: memoize input and textarea on export
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { range } from "fp-ts/NonEmptyArray";
|
import { range } from "fp-ts/NonEmptyArray";
|
||||||
import * as t from "io-ts";
|
import * as t from "io-ts";
|
||||||
|
|
||||||
@@ -54,13 +54,16 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onGeneratesChange: InputProps["onChange"] = ({ currentTarget: { value } }) => {
|
const onGeneratesChange: NonNullable<InputProps["onChange"]> = useCallback(
|
||||||
const newGenerates = Number(value);
|
({ currentTarget: { value } }) => {
|
||||||
|
const newGenerates = Number(value);
|
||||||
|
|
||||||
if (newGenerates >= 1 && newGenerates <= 1000) {
|
if (newGenerates >= 1 && newGenerates <= 1000) {
|
||||||
setGenerates(newGenerates);
|
setGenerates(newGenerates);
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const onGenerateClick = () => {
|
const onGenerateClick = () => {
|
||||||
const newUuids = range(1, generates).map(_ => uuid(uuidVersion, hyphens, uppercase));
|
const newUuids = range(1, generates).map(_ => uuid(uuidVersion, hyphens, uppercase));
|
||||||
@@ -121,18 +124,6 @@ export default function Page() {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const generatesInput = useMemo(
|
|
||||||
() => (
|
|
||||||
<Input
|
|
||||||
className="w-24 font-sans"
|
|
||||||
type="number"
|
|
||||||
value={generates}
|
|
||||||
onChange={onGeneratesChange}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[generates]
|
|
||||||
);
|
|
||||||
|
|
||||||
const uuidsCopyButton = <CopyButton text={uuidsString} />;
|
const uuidsCopyButton = <CopyButton text={uuidsString} />;
|
||||||
const uuidsClearButton = <ClearButton onClick={clearUuids} iconOnly aria-label="clear uuids" />;
|
const uuidsClearButton = <ClearButton onClick={clearUuids} iconOnly aria-label="clear uuids" />;
|
||||||
|
|
||||||
@@ -149,7 +140,12 @@ export default function Page() {
|
|||||||
Generate UUID(s)
|
Generate UUID(s)
|
||||||
</Button>
|
</Button>
|
||||||
<span>×</span>
|
<span>×</span>
|
||||||
{generatesInput}
|
<Input
|
||||||
|
className="w-24 font-sans"
|
||||||
|
type="number"
|
||||||
|
value={generates}
|
||||||
|
onChange={onGeneratesChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
<PageSection title="UUID(s)" control={uuidsControl}>
|
<PageSection title="UUID(s)" control={uuidsControl}>
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import equal from "react-fast-compare";
|
||||||
|
|
||||||
import { cn } from "@/lib/style";
|
import { cn } from "@/lib/style";
|
||||||
|
|
||||||
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||||
|
|
||||||
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
const RawInput = React.forwardRef<HTMLInputElement, InputProps>(({ className, ...props }, ref) => (
|
||||||
({ className, ...props }, ref) => (
|
<input
|
||||||
<input
|
{...{ ref }}
|
||||||
{...{ ref }}
|
className={cn(
|
||||||
className={cn(
|
"border-b-1 flex h-9 w-full rounded border border-b-muted-foreground bg-input px-3 py-2 font-mono outline-none placeholder:text-muted-foreground hover:bg-input-hover focus:border-b-2 focus:border-b-indicator focus:bg-input-focus focus:pb-[7px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
"border-b-1 flex h-9 w-full rounded border border-b-muted-foreground bg-input px-3 py-2 font-mono outline-none placeholder:text-muted-foreground hover:bg-input-hover focus:border-b-2 focus:border-b-indicator focus:bg-input-focus focus:pb-[7px] disabled:cursor-not-allowed disabled:opacity-50",
|
className
|
||||||
className
|
)}
|
||||||
)}
|
spellCheck="false"
|
||||||
spellCheck="false"
|
{...props}
|
||||||
{...props}
|
/>
|
||||||
/>
|
));
|
||||||
)
|
RawInput.displayName = "RawInput";
|
||||||
);
|
|
||||||
Input.displayName = "Input";
|
export const Input = React.memo(RawInput, equal);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import equal from "react-fast-compare";
|
||||||
|
|
||||||
import { cn } from "@/lib/style";
|
import { cn } from "@/lib/style";
|
||||||
|
|
||||||
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
||||||
|
|
||||||
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
export const RawTextarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||||
({ className, ...props }, ref) => (
|
({ className, ...props }, ref) => (
|
||||||
<textarea
|
<textarea
|
||||||
{...{ ref }}
|
{...{ ref }}
|
||||||
@@ -17,4 +18,6 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
Textarea.displayName = "Textarea";
|
RawTextarea.displayName = "RawTextarea";
|
||||||
|
|
||||||
|
export const Textarea = React.memo(RawTextarea, equal);
|
||||||
|
|||||||
Reference in New Issue
Block a user