Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

111
Visualizações
Scroll to anchor when Component is fully rendered in React functional component

This a (very) simplified version of my component:

export const DynamicComponent: FC<DynamicComponentProps> = (props) => {
  const ref = useRef<HTMLElement>(null);
  const [isSticked, setIsSticked] = useState(false);
  const parentSticked = useContext(StickyContext);
  const [overridedStyles, setOverridedStyles] = useState(props.styles ?? {});
  const [overridedArgs, setOverridedArgs] = useState(props.args ?? {});
  const { config } = useContext(GlobalContext);
  const data = useContext(DataContext);
  const [state, setState] = useContext(StateContext);

  const mountComponent = useMemo(() => {
    if (typeof props.mount === "undefined") return true;
    if (typeof props.mount === "boolean") return props.mount;
    if (typeof props.mount === "number") return props.mount === 1;
    if (typeof props.mount === "string") {
      let mount = stateParser.parse(props.mount, state) as unknown;
      return mount == true;
    }
    return false;
  }, [state, props.mount]);



  useLayoutEffect(() => {
    setTimeout(() => {
      const anchorHash = location.hash;
      if (
        anchorHash &&
        document &&
        document.querySelector(anchorHash) &&
        !document
          .querySelector(anchorHash)
          ?.classList.contains("already-scrolled")
      ) {
        document?.querySelector(anchorHash)?.scrollIntoView();
        document?.querySelector(anchorHash)?.classList.add("already-scrolled");
      }
    }, 50);
  }, []);

  let output = mountComponent ? (
    <StickyContext.Provider value={{ sticked: isSticked }}>
      <StyledDynamicComponent
        {...props}
        ref={ref}
        isSticked={applyStickedStyles}
        args={overridedArgs}
        styles={overridedStyles}
      />
    </StickyContext.Provider>
  ) : null;

  return output;
};

The code inside the useLayoutEffect won't run correctly without the setTimeout because the component is not fully rendered and document?.querySelector(anchorHash) does not exist yet..

Tried with a window.onload but the code inside it will never run..

Is there a way to prevent using that horrendous setTimeout?

Also please note that the anchor or the anchored element are optional so I don't know how to use callaback refs

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Don't use document.querySelector and don't check class names, if you can use states for it.

You don't need setTimeout at all, as useEffect and useEffectLayout are more or less the same as componentDidMount:

If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate. However, we recommend starting with useEffect first and only trying useLayoutEffect if that causes a problem. useLayoutEffect-Docs

I tried to reduce your samle a little bit more and made it debuggable in the codesandbox (hopefully keeping your logic in tact).

Edit React PlayGround (forked)

But the most important part would be the following:

const ref = useRef();

useEffect(() => {
    if (!ref.current || !document) {
      return;
    }

    // check if a hash is provided
    // possible todo: is the current element id the same as the provided location hash id
    if(!location.hash) {
      return true;
    }

    // check if we've scrolled already
    if(scrolled) {
      return;
    }

    ref.current.scrollIntoView();

    console.log("scroll to view", ref);
    setScrolled(true);
}, [ref, location, scrolled]);


Your component will then be rendered each time, the ref, location, or scrolled vars have changed, but it should only scroll into view, if it hasn't done that before.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda