Is it possible to force running code at server-side? #10949
-
|
Is there a way to force the code to run before the page as are generated? So I have some component that modify a state. What I observe that these state modifications happen on browser/client. I've read that using I'm using Cannot update a component (`StructuredDataProvider`) while rendering a different component (`StateModifyingComponent`).This happens because a component mutates the state, while other components renders the result of the state in My use-case in detailI'm using Provider pattern following Provider codeexport function StructuredDataProvider(props: Props): ReactNode {
const [nodes, setNodes] = useState<Thing[]>([]);
const registerNode: StructuredDataContextType['registerNode'] = (...newNodes) => {
setNodes((oldNodes) => {
ensureNoMissingIds(newNodes);
const existingIds = oldNodes.map((node) => node['@id']);
const missingNodes = newNodes.filter((newNode) => !existingIds.includes(newNode['@id']));
if (missingNodes.length === 0) {
return oldNodes;
}
return [
...oldNodes,
...newNodes,
];
});
};
const unregisterNode: StructuredDataContextType['unregisterNode'] = (...nodesToRemove) => {
setNodes((oldNodes) => {
ensureNoMissingIds(nodesToRemove);
const idsToRemove = nodesToRemove.map((node) => node['@id']);
const newNodes = nodesToRemove.filter((node) => idsToRemove.includes(node['@id']));
if (newNodes.length === oldNodes.length) {
return oldNodes;
}
return newNodes;
});
}
const getAllNodes: StructuredDataContextType['getAllNodes'] = () => nodes;
return (
<StructuredDataContext.Provider value={{ registerNode, getAllNodes, unregisterNode }}>
{props.children}
</StructuredDataContext.Provider>
);
}The components inside the provider uses I use `addStructuredData` function to manipulate state in other componentsfunction useStructuredDataContext(): StructuredDataContextType {
const context = useContext(StructuredDataContext);
if (!context) {
throw new Error('useNodes must be used within a StructuredDataProvider');
}
return context;
}
export const addStructuredData: StructuredDataContextType['registerNode'] = (...args) => {
const { registerNode, unregisterNode } = useStructuredDataContext();
useEffect(() => { // Do not execute affecting rendering
registerNode(...args);
return () => { // Cleanup on component unmount
unregisterNode(...args);
};
}, [] /* execute only once, initially */ );
}I want these state manipulations to happen before rendering but they happen after rendering on client side browser javascript. After state manipulations (all components mutate state), I render final state using `useStructuredData` to render statefunction useStructuredDataContext(): StructuredDataContextType {
const context = useContext(StructuredDataContext);
if (!context) {
throw new Error('useNodes must be used within a StructuredDataProvider');
}
return context;
}
export function useStructuredData(): Thing[] {
const context = useStructuredDataContext();
const nodes = context.getAllNodes();
return nodes;
}My goal is that all usages of state manipulation ( |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
|
Sorry but it is very difficult to understand what you try to achieve. Please create a minimal/simplified reproduction of that problem Most likely it's not possible no. First, Also, hooks are called on the client-side (apart from a few exceptions that you can ignore), so no, it's not possible to use a React context on the server side. Once your provider has "collected" all the data it needs, what do you plan to do with it? Render it in However, you can "collect" data while doing that unique server render: this is actually what React Helmet is doing under the hood, but since we have already rendered the React page, the collected data has to be injected into the page though other means (which is what Docusaurus does under the hood for you). |
Beta Was this translation helpful? Give feedback.
-
|
Hi slorber, Thank you again for your guidance. I appreciate a lot getting your guidance. I may be messing up things but I'm happy that you figured out the issue even though I may have been cryptic. I'll try to explain but if it creates too much of a cognitive load, I'll try to isolate the issue and create a separate repository for it. If I go back to real problem I'm solving. Google requires only single
Studying your answer, I understand that the render pass is single, so |
Beta Was this translation helpful? Give feedback.

Unfortunately, I don't see any solution: you have to aggregate all the FAQ data into a single place upfront so that you can render them in a single
<Head>declaration. You can't collect FAQ questions while rendering, and then render them in a subsequent render.