New Jul 31, 2026

Is it possible to remove the use of useEffect or are they unavoidable?

Libraries, Frameworks, etc. All from Newest questions tagged reactjs - Stack Overflow View Is it possible to remove the use of useEffect or are they unavoidable? on stackoverflow.com

I think that useEffect can be avoided here. Essentially what we are doing is to persist the state in query params, so whenever the user clicks on a node we change the query param (nodeid) and the other thing is if the user shares this URL with others we use this same nodeID to restore the tree view.

You can imagine the data structure to be a DAG Tree.

This looks like a good case for using useEffect (escape hatch from React and syncing React with URL - window) but I still think this is not the best way to do it.

const SELECTED_NODE_URL_PARAM = 'nodeId';

export const useNodeSelectionUrlSync = () => { console.log('hook re-rendering');

const { setSearchedNodeWithAncestors } = useNodesData(); const { selectedNode, setSelectedNode } = useNodesUI();

// Restore selection from URL when the component mounts. useEffect(() => { console.log('useEffect 1 ran');

if (typeof window === 'undefined') return;

const url = new URL(window.location.href);

const linkedNodeId = url.searchParams.get(SELECTED_NODE_URL_PARAM);

if (!linkedNodeId) return;

setSearchedNodeWithAncestors(linkedNodeId) .then((result) => { if (result?.targetNode) { setSelectedNode(result.targetNode); } else { url.searchParams.delete(SELECTED_NODE_URL_PARAM); const search = url.searchParams.toString(); const nextUrl = ${url.pathname}${search ? ?${search} : ''}${url.hash}; window.history.replaceState(null, '', nextUrl); } }) .catch(() => { url.searchParams.delete(SELECTED_NODE_URL_PARAM); const search = url.searchParams.toString(); const nextUrl = ${url.pathname}${search ? ?${search} : ''}${url.hash}; window.history.replaceState(null, '', nextUrl); }); }, [setSearchedNodeWithAncestors, setSelectedNode]);

// Keep the URL in sync with the currently selected node. useEffect(() => { console.log('useEffect 2 ran');

if (typeof window === 'undefined') return;

const url = new URL(window.location.href); const currentNodeId = url.searchParams.get(SELECTED_NODE_URL_PARAM); const selectedNodeId = selectedNode?.node.id;

if (selectedNodeId) { if (currentNodeId === selectedNodeId) return; url.searchParams.set(SELECTED_NODE_URL_PARAM, selectedNodeId); } else if (currentNodeId) { url.searchParams.delete(SELECTED_NODE_URL_PARAM); } else { return; }

const search = url.searchParams.toString(); const nextUrl = ${url.pathname}${search ? ?${search} : ''}${url.hash}; window.history.replaceState(null, '', nextUrl); }, [selectedNode]); };

Scroll to top