[]previous and next page

What runs on the server

When renderToString, renderToStringAsync or renderToStream render a component, the component body runs, memos compute, and onCleanup callbacks run when the…

For agentsUpdated

When renderToString, renderToStringAsync or renderToStream render a component, the component body runs, memos compute, and onCleanup callbacks run when the render ends. useEffect, useRenderEffect and onMount do nothing: no node is created and the function is never called. Code that touches window, document or timers belongs in those three, not in the component body.

src/server-order.tsxtsx
import { onCleanup, onMount, useEffect, useMemo, useRenderEffect, useStore } from "@shadow-js/core";
import { renderToString } from "@shadow-js/web/server";

const log: string[] = [];

function App() {
  const [n] = useStore(1);
  const doubled = useMemo(() => {
    log.push("memo");
    return n() * 2;
  });
  useEffect(() => {
    log.push("effect");
  });
  useRenderEffect(() => {
    log.push("render effect");
  });
  onMount(() => {
    log.push("mount");
  });
  onCleanup(() => {
    log.push("cleanup");
  });
  log.push("body");
  return <p>{doubled()}</p>;
}

renderToString(() => <App />);
console.log(log.join(","));
Expected output
memo,body,cleanup

On the client the same component renders again (or is hydrated) and its effects run after the first flush. See SSR, hydration and streaming.