reactjs - Videreføre flere ref i typescript


Jeg prøver å videreformidle et objekt av ref i TypeScript, men jeg støter på et problem med å korrekt typere dem.

Dette er mine refs og hvordan jeg sender dem inn i komponenten min.

const storyRef = useRef<HTMLElement>(null);
const parcoursRef = useRef<HTMLElement>(null);
const projectRef = useRef<HTMLElement>(null);

const refs = useRef({ storyRef, parcoursRef, projectRef });

...
...

<Navbar ref={refs} setShowModal={setShowModal} />

Inne i komponenten min skriver jeg dem på denne måten:

const Navbar = React.forwardRef<
    React.MutableRefObject<{
        storyRef: React.RefObject<HTMLElement>;
        parcoursRef: React.RefObject<HTMLElement>;
        projectRef: React.RefObject<HTMLElement>;
    }>,
    ModalProps
>(({ setShowModal }, ref) => {

Dette er feilen jeg har:

Type 'MutableRefObject<{ storyRef: RefObject; parcoursRef: RefObject; projectRef: RefObject; }>' kan ikke tilordnes typen 'Ref> | undefined'. Type 'MutableRefObject<{ storyRef: RefObject; parcoursRef: RefObject; projectRef: RefObject; }>' kan ikke tilordnes typen 'RefObject>'.

Svar #1

React støtter ikke direkte videresending av flere refs i TypeScript. Men frykt ikke, det finnes en reell løsning kalt useImperativeHandle-hooken. Du kan også lage uendelige refs til barneelementer og til og med funksjoner.

Mitt eksempel har en barnekomponent som viser at du enkelt kan sende videre refs til:

  • Enhver HTML-element
  • Funksjoner

Alt med TypeScript-fordeler.

Fullt fungerende eksempel:

//Child Component 

//Create your ref types here
export type RefHandler = {
  pressAlert: () => void;
  inputRef: RefObject<HTMLInputElement>;
};

const Child = forwardRef<RefHandler, Props>((props, ref) => {
  const submitRef = useRef<HTMLButtonElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  //Initialise your refs here
  useImperativeHandle(ref, () => ({
    inputRef: inputRef,
    pressAlert: () => submitRef?.current?.click()
  }));

  return (
    <div>
      <p>Child Component</p>
      <input type="text" value="lorem ipsum" ref={inputRef} />
      <br />
      <button onClick={() => alert("Alert pressed")} ref={submitRef}>
        Alert
      </button>
    </div>
  );
});
//Parent 
export default function Parent() {
  const childRef = useRef<RefHandler>(null);

  return (
    <>
      <p>Parent</p>
      <button
        onClick={() => {
          alert(childRef?.current?.inputRef?.current?.value);
        }}
      >
        Read child input
      </button>
      <button onClick={() => childRef?.current?.pressAlert()}>
        Press child button
      </button>
      <hr />
      <Child ref={childRef} />
    </>
  );
}

Svar #2

const refs = useRef({ storyRef, parcoursRef, projectRef });

Prøv å lage en typet versjon for denne useRef også som nedenfor, og prøv deretter på nytt:

const refs = useRef<{storyRef: type, ...restProps}>({ storyRef, parcoursRef, projectRef });

Relaterte artikler