You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SSR应用:如何区分hydrate/render渲染及服务端与浏览器渲染?

React SSR: Detecting Hydrate vs Render & Server/Browser Differentiation

Hey there! Let’s break down your two React SSR questions with practical, actionable solutions:


1. Detecting if Hydrate or Render is Used

React doesn’t expose a built-in property to directly check if you’re using hydrate or render, but you can implement reliable checks with these approaches:

  • Check for SSR-rendered DOM content
    Before initializing React on the client, inspect your root container. If it has existing child elements (from server-side rendering), use hydrate; otherwise, use render. Here’s a code example:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    
    const rootElement = document.getElementById('root');
    
    if (rootElement.hasChildNodes()) {
      // SSR content exists, use hydrate
      const root = ReactDOM.hydrateRoot(rootElement, <App />);
    } else {
      // No SSR content, use render
      const root = ReactDOM.createRoot(rootElement);
      root.render(<App />);
    }
    
  • Add a custom SSR marker attribute
    When rendering on the server, add a custom data attribute to your root element (e.g., data-ssr="true"). Then check for this attribute on the client:
    Server-side (e.g., with Express):

    // Server render logic
    const html = ReactDOMServer.renderToString(<App />);
    res.send(`
      <!DOCTYPE html>
      <html>
        <body>
          <div id="root" data-ssr="true">${html}</div>
        </body>
      </html>
    `);
    

    Client-side:

    const rootElement = document.getElementById('root');
    const isSSR = rootElement.getAttribute('data-ssr') === 'true';
    
    if (isSSR) {
      ReactDOM.hydrateRoot(rootElement, <App />);
    } else {
      ReactDOM.createRoot(rootElement).render(<App />);
    }
    

2. Differentiating Server vs Browser Execution

To run code only on the server or only in the browser, use these proven methods:

  • Check for browser-specific globals
    The simplest way is to check if window exists (since it’s only available in browsers):

    function MyComponent() {
      if (typeof window !== 'undefined') {
        // This code runs only in the browser
        console.log('Running in browser');
      } else {
        // This code runs only on the server
        console.log('Running on server');
      }
      return <div>Hello World</div>;
    }
    
  • Use React lifecycle hooks/effects
    Client-side-only hooks like useEffect (or componentDidMount for class components) don’t execute during server rendering. Perfect for code that relies on browser APIs:

    import { useEffect } from 'react';
    
    function ClientOnlyComponent() {
      useEffect(() => {
        // Runs ONLY in the browser after hydration
        const timer = setInterval(() => console.log('Tick'), 1000);
        return () => clearInterval(timer);
      }, []);
    
      return <div>Client-only content</div>;
    }
    
  • Custom environment variables
    Set a variable during build/execution to flag the environment. For example, in your Node.js server:

    // Server-side: Set IS_BROWSER to false
    global.IS_BROWSER = false;
    

    In your client-side build config (e.g., Webpack/Vite), define:

    // Client-side: Set IS_BROWSER to true
    define: {
      IS_BROWSER: true
    }
    

    Then use it in your components:

    if (IS_BROWSER) {
      // Browser-only logic
    } else {
      // Server-only logic
    }
    
  • Route-specific differentiation
    Use React Router’s StaticRouter for server rendering and BrowserRouter for the client:
    Server-side:

    import { StaticRouter } from 'react-router-dom/server';
    
    const html = ReactDOMServer.renderToString(
      <StaticRouter location={req.url}>
        <App />
      </StaticRouter>
    );
    

    Client-side:

    import { BrowserRouter } from 'react-router-dom';
    
    ReactDOM.hydrateRoot(
      document.getElementById('root'),
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );
    

内容的提问来源于stack exchange,提问作者sunknudsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:12:56