Skip to content

Uncontrolled Component

SeungJin Choi edited this page Jun 14, 2023 · 1 revision

๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ

J Design System์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•œ ๊ณผ์ œ๋Š” '์‚ฌ์šฉ์ž ๊ฒฝํ—˜'์ด์—ˆ์Šต๋‹ˆ๋‹ค. UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‚ค๋ณด๋“œ ์ œ์–ด๋ฅผ ํ†ตํ•ด ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์œผ๋ฉฐ, ์ด๋ฅผ ์œ„ํ•ด ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ React์˜ ์ƒํƒœ ๊ด€๋ฆฌ ํ๋ฆ„์—์„œ ๋ฒ—์–ด๋‚˜ DOM ์š”์†Œ์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

support React Hook Form

React Hook Form์€ ์ธ๊ธฐ๊ฐ€ ๋งŽ์€ React Form ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. J Design System์„ ์‚ฌ์šฉํ•˜๋ฉด React Hook Form์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก register ref Ojbect๋ฅผ ์ˆ˜์šฉํ•˜๊ธฐ ์œ„ํ•ด forwardRef๋กœ ๊ฐ์‹ธ์ฃผ์–ด React Hook Form๊ณผ ์—ฐ๊ณ„๋  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ณ ๋ คํ•˜์˜€์Šต๋‹ˆ๋‹ค.

//Textarea.tsx
type ExtendedTextAreaProps = TextAreaProps & { Label?: typeof TextareaLabel };
export const Textarea = Object.assign(
  forwardRef<HTMLTextAreaElement, ExtendedTextAreaProps>((textAreaProps, ref) => {
    const { children, ...propsWithoutChildren } = textAreaProps;
    const textareaLabel = filterComponent(children, TextareaLabel, true);
    return (
      <TextareaProvider textareaProps={propsWithoutChildren}>
        <TextareaContainer children={textareaLabel} ref={ref} />
      </TextareaProvider>
    );
  }),
  {
    Label: TextareaLabel
  }
);
//TextareaContainer
export const TextareaContainer = forwardRef(
  (props: { children: React.ReactNode }, externalRef: ForwardedRef<any> | null) => {
    const { styleProps, textareaProps, textareaId } = useContext<ReturnContext>(TextareaContext);
    const { onChange, ...attributesWithoutOnChange } = textareaProps;
    const textareaStyle = createTextareaStyle(styleProps, TEXTAREA_PLACEHOLDER_COLOR);
    const wrapperStyle = createWrapperStyle(styleProps.width);
    const { textareaRef, handleChange } = useSmart(onChange, styleProps.resize);
    const { getLabelId } = useTextarea();
    const labelId = getLabelId(props.children);

    return (
      <div css={wrapperStyle}>
        {props.children}
        <textarea
          role="textbox"
          aria-multiline="true"
          id={textareaId}
          css={textareaStyle}
          ref={e => {
            if (typeof externalRef === 'function') {
              externalRef(e);
            }
            textareaRef.current = e;
          }}
          onChange={handleChange()}
          {...(textareaProps.placeholder && { 'aria-placeholder': textareaProps.placeholder })}
          {...(labelId && { 'aria-labelledby': labelId })}
          {...attributesWithoutOnChange}
        />
      </div>
    );
  }
);

์œ„์˜ ์˜ˆ์‹œ๋Š” ์‹ค์ œ ์ž‘์„ฑ๋œ Textarea ์ฝ”๋“œ ์ด๋ฉฐ, Input, Radio, Checkbox ๋“ฑ Form์— ํ•„์š”ํ•œ ์š”์†Œ๋“ค๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Clone this wiki locally