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?