Definitelytyped: [@types/react] useRef λ°˜ν™˜ μœ ν˜•μ΄ ref prop μœ ν˜•κ³Ό μΆ©λŒν•©λ‹ˆλ‹€.

에 λ§Œλ“  2019λ…„ 05μ›” 19일  Β·  12μ½”λ©˜νŠΈ  Β·  좜처: DefinitelyTyped/DefinitelyTyped

  • [x] @types/16.8.17 νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•΄ λ³΄μ•˜λŠ”λ° λ¬Έμ œκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
  • [x] μ•ˆμ •μ μΈ μ΅œμ‹  λ²„μ „μ˜ tscλ₯Ό μ‚¬μš©ν•΄ λ³΄μ•˜μŠ΅λ‹ˆλ‹€. https://www.npmjs.com/package/typescript
  • [x] StackOverflow 에 μ ν•©ν•˜μ§€ μ•Šμ€ 질문이 μžˆμŠ΅λ‹ˆλ‹€. (μ μ ˆν•œ 질문이 있으면 κ±°κΈ°μ—μ„œ μ§ˆλ¬Έν•˜μ‹­μ‹œμ˜€.)
Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Types of property 'current' are incompatible.
      Type 'HTMLDivElement | undefined' is not assignable to type 'HTMLDivElement | null'.
        Type 'undefined' is not assignable to type 'HTMLDivElement | null'.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ•½κ°„ κΉ”λ”ν•œ 해결책은 useRef ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ initialValueλ₯Ό null둜 μ„€μ •ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

const componentRef = useRef<HTMLDivElement>(null);

이것은 componentRef = HTMLDivElement | null 을 보μž₯ν•©λ‹ˆλ‹€. μ΄λŠ” HTMLDivElement | undefined λ³΄λ‹€λŠ” ref μ†Œν’ˆμ΄ κΈ°λŒ€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

λͺ¨λ“  12 λŒ“κΈ€

νŽΈμ§‘ 2: λ‚΄ μ†”λ£¨μ…˜μ„ λ¬΄μ‹œν•˜κ³  μ•„λž˜ μ†”λ£¨μ…˜μ„ μ‚¬μš©ν•˜μ„Έμš”. :)

λ‚˜λŠ” ν˜„μž¬ 같은 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. ν˜Ήμ‹œ 이미 해결책을 μ°Ύμ•˜μŠ΅λ‹ˆκΉŒ?

νŽΈμ§‘ : λ‚˜λŠ” μ§€κΈˆ 이것을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λΆ„λͺ…νžˆ κ·Έλ ‡κ²Œ μ˜ˆμ˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. ν•΄κ²°μ±… :

const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;

μ—¬κΈ°μ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041

μ•½κ°„ κΉ”λ”ν•œ 해결책은 useRef ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ initialValueλ₯Ό null둜 μ„€μ •ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

const componentRef = useRef<HTMLDivElement>(null);

이것은 componentRef = HTMLDivElement | null 을 보μž₯ν•©λ‹ˆλ‹€. μ΄λŠ” HTMLDivElement | undefined λ³΄λ‹€λŠ” ref μ†Œν’ˆμ΄ κΈ°λŒ€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

@shane935 λ‹˜ μ˜€λŠ˜λ„ μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€ πŸ™ŒπŸ»

λ‹€μŒκ³Ό 같이 undefined λ₯Ό RefObject<T>.current 에 μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null;
}

κ·Έλž˜μ„œ μ½λŠ”λ‹€

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null | undefined;
}

버그가 μ•„λ‹ˆλΌ 합법적인 μž…λ ₯ 였λ₯˜λ₯Ό μž‘λŠ” κ²ƒμž…λ‹ˆλ‹€.

μžμ„Έν•œ λ‚΄μš©μ€ https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment -529749802λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

@Jessidhia κ°€ λ§ν–ˆλ“―μ΄ 버그가 μ•„λ‹™λ‹ˆλ‹€. μ•„λ§ˆλ„ λ‹€μŒκ³Ό 같이 μž‘μ„±ν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€.

import React, {
  forwardRef,
  ForwardRefRenderFunction,
  useImperativeHandle,
  useRef,
  PropsWithChildren,
} from "react";

interface Props {}
interface Ref {
  value: string;
  setValue: (value: string) => void;
}

const InputEmail: ForwardRefRenderFunction<Ref, PropsWithChildren<Props>> = (
  props,
  ref
) => {
  // hooks
  const inputElement = useRef<HTMLInputElement | null>(null);
  useImperativeHandle(ref, () => {
    return {
      value: inputElement.current ? inputElement.current.value : "",
      setValue: (value: string) => {
        inputElement.current && (inputElement.current.value = value);
      },
    };
  });

  // render
  return (
    <div>
      <input
        type="text"
        ref={inputElement}
        defaultValue="[email protected]"
        disabled
      />
    </div>
  );
};

const Component = forwardRef(InputEmail);

export default Component;

이것이 λͺ¨λ“  μ‚¬λžŒμ˜ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμ„μ§€ ν™•μ‹ ν•  수 μ—†μœΌλ©° 이 λ¬Έμ œμ— λŒ€ν•œ 전문가도 μ•„λ‹ˆμ§€λ§Œ λ‚΄κ°€ ref둜 μ „λ‹¬ν•œ λ‚΄μš©κ³Ό refλ₯Ό μ „λ‹¬ν•œ ꡬ성 μš”μ†Œμ˜ μ‹€μ œ ref μœ ν˜•μ„ μ‚΄νŽ΄λ³Έ ν›„ , μΈν„°νŽ˜μ΄μŠ€κ°€ 잘λͺ»λœ 것 κ°™μ•˜μŠ΅λ‹ˆλ‹€.

μ²˜μŒμ—λŠ” μˆ˜μ‹  ꡬ성 μš”μ†Œμ— λŒ€ν•΄ λ‹€μŒκ³Ό 같은 μ†Œν’ˆ μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>

λ‚΄κ°€ λ³€κ²½ν•œ 것:

type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>

그런 λ‹€μŒ μž…λ ₯ 였λ₯˜κ°€ μ‚¬λΌμ‘ŒμŠ΅λ‹ˆλ‹€.

λ‚˜λ³΄λ‹€ 더 많이 μ•„λŠ” μ²™ ν•˜μ§€λŠ” μ•Šκ² μ§€λ§Œ HTMLProps μΈν„°νŽ˜μ΄μŠ€μ™€ React.forwardRef() ν•¨μˆ˜ μœ ν˜•μ˜ μœ ν˜•μ„ μ‚΄νŽ΄λ³΄λ©΄ RefAttributesλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŒμ„ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.. λ°”λ‘œ μœ„μ— ClassAttributesλ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.HTMLPropsλ₯Ό μž…λ ₯ν•˜μ‹­μ‹œμ˜€.ν™•μž₯ 쀑이며 κ·Έ 쀑 LegacyRefλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.λ‚΄ 타이핑 문제λ₯Ό μΌμœΌν‚¨ κ²ƒμœΌλ‘œ μƒκ°λ˜λŠ” μœ ν˜•.

이 ν”„λ‘œμ νŠΈμ—λŠ” useRef() 에 λŒ€ν•΄ 3개의 μ˜€λ²„λ‘œλ“œκ°€ μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. 3κ°œκ°€ λͺ¨λ‘ ν•„μš”ν•©λ‹ˆκΉŒ? useRef<T>(null) μΌ€μ΄μŠ€λŠ” κ°œλ°œμžκ°€ κ°€μž₯ 많이 μ‚¬μš©ν•˜λŠ” μΌ€μ΄μŠ€μΈ 것 κ°™μŠ΅λ‹ˆλ‹€.

    function useRef<T>(initialValue: T): MutableRefObject<T>;
    function useRef<T>(initialValue: T|null): RefObject<T>;
    function useRef<T = undefined>(): MutableRefObject<T | undefined>;
  1. 두 가지 λ³€κ²½ κ°€λŠ₯ν•œ μ˜€λ²„λ‘œλ“œμ˜ μ˜ˆμƒ μ‚¬μš© μ‚¬λ‘€λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?
  2. μ‚¬μš©μžκ°€ "μ˜¬λ°”λ₯Έ" κ³ΌλΆ€ν•˜λ₯Ό 더 μ‰½κ²Œ 찾을 수 μžˆλ„λ‘ μ§€μ›ν•˜λŠ” λ‹€λ₯Έ 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

RefObject 이 μžˆμŠ΅λ‹ˆλ‹€.

Screen Shot 2020-08-23 at 1 06 16 PM

ref μ†Œν’ˆμœΌλ‘œ Panel ꡬ성 μš”μ†Œμ— μ „λ‹¬ν•©λ‹ˆλ‹€.

Screen Shot 2020-08-23 at 1 06 04 PM

w/ forwardRef μ†ŒλΉ„ν•˜λ €κ³  ν•˜λ©΄ MutableRefObject λ©λ‹ˆλ‹€.

Screen Shot 2020-08-23 at 1 06 56 PM

이제 .current 속성을 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

Screen Shot 2020-08-23 at 1 10 27 PM

@Jessidhia @osf2e κ·€ν•˜μ˜ μ œμ•ˆμ€ 여기에 ν•΄λ‹Ήλ˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

λ‚΄κ°€ μ˜μ§€ν•΄μ•Ό ν•˜λŠ” ν•΄κ²° 방법:

        if (ref && (ref as RefObject<HTMLDivElement>).current) {
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              (ref as RefObject<
                HTMLDivElement
              >)!.current!.style.height = `${containerHeight}px`;
            }

react-native-web을 μ‚¬μš©ν•˜μ—¬ μ‚¬μš©ν•΄μ•Όν–ˆμŠ΅λ‹ˆλ‹€.

import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View>

Input μš”μ†Œμ— λŒ€ν•œ Ref에 이 λ¬Έμ œκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
κ·Έλž˜μ„œ useRef<HTMLDivElement>() -> useRef<HTMLInputElement>() μ—μ„œ μ „ν™˜ν–ˆλŠ”λ° μ •μƒμ μœΌλ‘œ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€.

@joshribakoff λ§€κ°œλ³€μˆ˜λ₯Ό 직접 μž…λ ₯ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

export const Panel = React.forwardRef((props: PanelProps, ref: React.RefObject<HTMLDivElement>) => {

κ·Έλ ‡κ²Œ ν•˜λ©΄ ref에 μ•‘μ„ΈμŠ€ν•  λ•Œ typecastν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
근데 μ™œ 이걸 ν•΄μ•Όν•˜λŠ”μ§€ 아직도 이해가 μ•ˆκ°...

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰