reactjs - Redirecționarea mai multor referințe în typescript


Încerc să transmit un obiect de referință în TypeScript, dar întâmpin o problemă în a le tipiza corect.

Acestea sunt referințele mele și cum le transmit în componenta mea.

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} />

În interiorul componentei mele le scriu astfel:

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

Aceasta este eroarea pe care o am:

Tipul 'MutableRefObject<{ storyRef: RefObject; parcoursRef: RefObject; projectRef: RefObject; }>' nu este atribuitabil tipului 'Ref> | undefined'. Tipul 'MutableRefObject<{ storyRef: RefObject; parcoursRef: RefObject; projectRef: RefObject; }>' nu este atribuitabil tipului 'RefObject>'.

Răspuns #1

React nu suportă direct redirecționarea mai multor ref-uri în TypeScript. Totuși, nu vă temeți, există o soluție reală numită hook-ul useImperativeHandle. De asemenea, puteți crea un număr nelimitat de refs către elementele copil și chiar funcții.

Exemplul meu are un component copil care arată că poți transfera cu ușurință referințele către:

  • Orice element html
  • Funcții

Totul cu avantajele TypeScript.

Exemplu complet funcțional:

//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} />
    </>
  );
}

Răspunsul #2

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

Încearcă să creezi o versiune tipizată pentru acest useRef, la fel ca mai jos, și apoi încearcă din nou:

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