學習進階使用

伺服器端渲染、伺服器端產生

React Flow 12 開始支援伺服器端渲染

這是一個進階的使用案例,並假設您已熟悉 React Flow。如果您是 React Flow 的新手,請查看我們的入門指南

在本指南中,您將學習如何設定 React Flow 以在伺服器上渲染流程圖,這將允許您

  • 在文件中顯示靜態 HTML 圖表
  • 在非 JavaScript 環境中渲染 React Flow 圖表
  • 動態產生 opengraph 圖片,在分享流程圖連結時顯示為嵌入內容

(如果您想要下載流程圖的圖片,我們在下載圖片範例中有一個更簡單的方法可以在客戶端進行。)

節點尺寸

您需要設定一些項目才能讓 React Flow 在伺服器上運作,最重要的是節點尺寸。React Flow 只有在節點有寬度和高度時才會渲染節點。通常,您傳遞的節點沒有特定的 widthheight,它們會被測量,並且尺寸會寫入 measured.widthmeasured.height。由於我們無法在伺服器上測量尺寸,因此我們需要明確傳遞它們。這可以使用 widthheightinitialWidthinitialHeight 節點屬性來完成。

const nodes = [
  {
    id: '1',
    type: 'default',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
    width: 100,
    height: 50,
  },
];

React Flow 現在知道節點的尺寸,並且可以在伺服器上渲染它。widthheight 屬性用作節點的內嵌樣式。如果您預期節點在客戶端上具有不同的尺寸,或者尺寸應該根據內容動態變化,則可以使用 initialWidthinitialHeight 屬性。它們僅用於第一次渲染(在伺服器上或在客戶端上),只要節點未被測量且未設定 measured.widthmeasured.height

💡

有兩種方法可以為伺服器端渲染指定節點尺寸

  1. widthheight 用於預先知道且不會變化的靜態尺寸。
  1. initialWidthinitialHeight 用於預先不知道或會變化的動態尺寸。

節點控制點位置

您可能也想在伺服器上渲染邊線。在客戶端,React Flow 會檢查控制點的位置並儲存該資訊以繪製邊線。由於我們無法在伺服器上測量控制點的位置,因此我們也需要傳遞此資訊。這可以使用節點的 handles 屬性來完成。

const nodes: Node[] = [
  {
    id: '1',
    type: 'default',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
    width: 100,
    height: 50,
    handles: [
      {
        type: 'target',
        position: Position.Top,
        x: 100 / 2,
        y: 0,
      },
      {
        type: 'source',
        position: Position.Bottom,
        x: 100 / 2,
        y: 50,
      },
    ],
  },
];

有了這些額外的資訊,React Flow 就知道足夠的控制點資訊,可以在伺服器上渲染邊線。如果您僅需渲染節點,則可以跳過此步驟。

在伺服器上使用 fitView

如果您知道 React Flow 容器本身的尺寸,甚至可以在伺服器上使用 fitView。為此,您需要將容器的 widthheight 傳遞給 ReactFlow 元件。

<ReactFlow nodes={nodes} edges={edges} fitView width={1000} height={500} />

這將計算視窗並在伺服器上設定 transform,以便將所有節點都包含在視窗中。

搭配 <ReactFlowProvider> 使用

如果您正在使用 ReactFlowProvider,您可以將 initialNodesinitialEdges 和可選的包裝器尺寸(initialWidthinitialHeight)和 fitView 傳遞給提供者。

<ReactFlowProvider
  initialNodes={nodes}
  initialEdges={edges}
  initialWidth={1000}
  initialHeight={500}
  fitView
>
  <App />
</ReactFlowProvider>