Timeline
最新消息?
我们一直在改进 React Flow 的文档和库。
这是我们到目前为止添加或更改的事项的时间表。

React 流 12.10.1
补丁更改
🌐 Patch Changes

React 流 12.10.0
小幅更改
🌐 Minor Changes
补丁更改
🌐 Patch Changes
- #5629 谢谢 @AlaricBaraou ! - 防止在
FlowRenderer中不必要的重新渲染 - #5592 感谢 @svilen-ivanov-kubit ! - 在应用更改时总是创建一个新的测量对象。
- #5635 感谢 @tornado-softwares ! - 当用户使用键盘移动节点时,更新正在进行的连接。

React Flow 用户界面组件已更新到 React 19 和 Tailwind CSS 4
我们的 React Flow UI 组件已更新,以支持最新版本的 shadcn/ui,适用于 React 19 和 Tailwind 4!
🌐 Our React Flow UI components have been updated to support the latest version of shadcn/ui, on React 19 and Tailwind 4!
此更新包括来自最新版本的 shadcn/ui 的全新外观,以及一个新的 UI 组件教程,帮助你快速入门。
🌐 This update includes a fresh look from the latest version of shadcn/ui , and a new UI Components tutorial to get you started.
如何升级你的项目
🌐 How to upgrade your project
要升级你的项目,请按照以下步骤操作。
🌐 To upgrade your project, follow the steps below.
第1步:更新依赖。
🌐 Step 1: Update dependencies.
npm install react@latest react-dom@latest tailwindcss@latest或者在 package.json 中手动操作,然后运行
🌐 Or do so manually in package.json, and then run
npm install步骤 2:运行 Tailwind CSS 升级代码变换工具。
🌐 Step 2: Run the Tailwind CSS upgrade codemod.
在shadcn/ui Tailwind CSS 4 升级指南 中了解更多可用的代码修改工具。
🌐 Read more about available codemods in the shadcn/ui Tailwind CSS 4 upgrade guide .
npx @tailwindcss/upgrade第3步:将 React Flow 样式移到 global.css 文件中。
🌐 Step 3: Move the React Flow styles to the global.css file.
重要: Tailwind CSS 4 现在完全在 CSS 中配置。你不再是在 App.tsx 中导入你的 @xyflow/react/dist/style.css 文件,而是需要在导入 tailwindcss 之后,在你的 global.css 文件中导入它。
// Tailwind CSS 3
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
// Tailwind CSS 4
+@import "tailwindcss";
+@import "tw-animate-css";
+@layer base {
+ @import "@xyflow/react/dist/style.css";
+}我们建议从你的项目中移除旧的 js/ts Tailwind 配置,并迁移到仅使用 CSS 变量的新配置。这可以让事情变得更简单:你可以在单个 CSS 文件中配置与应用设计系统和外观相关的所有内容。
🌐 We recommend removing the old js/ts tailwind configuration from your project, and migrating to the new CSS-variable-only configuration.
This can make things a lot simpler: you can configure everything related to your application’s design system and look in a single CSS file.
-import '@xyflow/react/dist/style.css';
import "./globals.css";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}第4步:更新组件
🌐 Step 4: Update the components
对于你想要更新的每个组件,你可以运行以下命令。
🌐 For each component you want to update, you can run the following commands.
如果它是一个 shadcn/ui 组件:
🌐 If it’s a shadcn/ui component:
npx shadcn@latest add component-name如果它是一个 React Flow UI 组件:
🌐 If it’s a React Flow UI component:
npx shadcn@latest add https://ui.reactflow.dev/component-name
React 流 12.9.0
此次更新非常重要!我们新增了一个 EdgeToolbar 组件,现在可以在节点上方开始选择,并且不同父节点的子节点将不再重叠:
🌐 This update is huge! We added a new EdgeToolbar component, it’s now possible to start a
selection above a node and child nodes of different parents won’t overlap anymore:
小幅更改
🌐 Minor Changes
补丁更改
🌐 Patch Changes



React 流 12.8.3
React Flow 的新版本已发布。在 12.8.3 版本中,你将获得许多错误修复以及对句柄的重大改进。现在可以将句柄的子内容放置在句柄本身之外,并且仍然可以将其用作连接的起点,正如你在这个示例中看到的:
🌐 A new version of React Flow is out. With 12.8.3 you get a lot of bug fixes and a great improvement for handles. It’s now possible to position child content of a handle outside of the handle itself and still use it as a starting point for connections as you can see in this example:
补丁更改
🌐 Patch Changes
- #5428 能够使用分离句柄内容作为连接的起点
- #5419 当标记颜色为空时,使边缘标记回退到
--xy-edge-strokeCSS 变量 - #5453 启用捕捉网格时捕捉选择而不是单独节点
- #5444 导出
MiniMapNode以用于自定义小地图节点 - #5415 允许标记类型使用字符串和枚举
- #5436 当 interactionWidth 为 0 时,防止在边缘的标记中添加 0
- #5443 将 1 用作交互式小地图缩放步长的默认值
- #5448 对于句柄
onConnect使用正确的HandleConnection类型 - #5420 从
Node的domAttributes中省略defaultValue以修复使用WritableDraft时的类型不兼容问题


重新刷洗 React 流 UI
我们对 React Flow UI(前称 React Flow 组件)进行了一些重大改进。这些变化增强了组件的功能、视觉外观和可用性,以改善整体开发者体验。
🌐 We have made some significant improvements to React Flow UI (formerly known as React Flow components). These changes enhance the functionality, visual look and usability of the components, to improive the general developer experience.
重新组织组件
🌐 Re-organize components
一些组件已被移到示例中,而其他组件已在新结构中合并:
🌐 Some components have been moved to examples, while others have been consolidated in a new structure:
- 节点工具:这些组件可以用作创建自定义节点的构建模块。
- 自定义节点:这些都是功能齐全的节点,可以直接在你的应用中使用。
- 句柄:这些组件用于在节点内部创建连接点。
- 自定义边缘:可直接使用的全功能边缘。
- 控件:交互式控件的集合。
- 杂项:各种不属于其他类别的实用组件,如
DevTools。
在 React Flow UI 页面 中找到它们全部。
🌐 Find all of them in the React Flow UI page.
BaseNode 增强功能
🌐 BaseNode enhancements
我们的 BaseNode 组件已经完全重新设计,以提供与 shadcn UI 以及我们其余的 React Flow UI 组件库 更加一致的体验。
🌐 Our BaseNode component has been fully revamped, to provide a more consistent experience with shadcn UI , and the rest of our React Flow UI component library.
新的 BaseNode 组件现在包括改进的样式和封装组件,符合 shadcn UI 设计原则。
🌐 The new BaseNode component now includes improved styling and wrapper components,
aligning to shadcn UI design principles.
就像一个 shadcn UI 卡片组件 ,BaseNode 组件现在也导出
🌐 Just like a shadcn UI Card component , the
BaseNode component now exports
BaseNodeHeader和BaseNodeHeaderTitle用于标题部分,BaseNodeContent用于主要内容区域,并且BaseNodeFooter用于页脚部分。
这个结构允许在节点内更好地组织内容,从而更容易创建复杂的节点布局。
🌐 This structure allows for better organization of content within the node, making it easier to create complex node layouts.
改进的示例和节点
🌐 Improved examples and nodes
我们还添加了一些新组件并改进了现有组件。我们的组件页面现在包括更全面的示例,展示组件的新功能和能力。例如:
🌐 We have also added a few new components and improved existing ones. Our component pages now include more comprehensive examples that showcase the new features and capabilities of the components. For example:
- 新的
NodeAppendix组件,可用于向节点添加额外的信息或控件,就像Node Badge一样! AnnotationNode组件已被移至BaseNode的示例用法,以演示如何为BaseNode进行样式设置。StatusIndicator现在包括一个带有覆盖旋转器的变体,以及改进的使用示例。TooltipNode组件已经得到改进,并已迁移到NodeTooltip。它不再是自定义节点,而是一个实用组件,你可以使用它来给自定义节点添加工具提示。
不再有 selected 属性
🌐 No more selected prop
你不再需要将 selected 属性传递给 BaseNode 或其相关组件。选中状态的样式现在由 Tailwind CSS 选择器自动处理。
🌐 You don’t need to pass the selected prop to the BaseNode or its related components
anymore. Styling the selected state is now handled automatically by tailwind CSS
selectors.
然而,selected 仍然是 React Flow 中节点的有效属性,你仍然可以在自定义组件中使用它来判断节点是否被选中。如果你不需要 selected 属性来进行自定义逻辑,而只是用于样式,你可以安全地从组件中移除它,并且可以参考 BaseNode 的实现方式来为自定义选中节点实现自定义样式。
🌐 However, selected is still a valid prop for nodes in React Flow, and you can still use
it to determine if a node is selected or not in your custom components. If you do not need
the selected prop for custom logic, but you only use it for styling, you can safely
remove it from your components, and you can follow how BaseNode is implemented to
achieve custom styling for your custom selected nodes.
export const BaseNode = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
'relative rounded-md border bg-card text-card-foreground',
'hover:ring-1',
// React Flow displays node elements inside of a `NodeWrapper` component,
// which compiles down to a div with the class `react-flow__node`.
// When a node is selected, the class `selected` is added to the
// `react-flow__node` element. This allows us to style the node when it
// is selected, using Tailwind's `&` selector.
'[.react-flow\\_\\_node.selected_&]:border-muted-foreground',
'[.react-flow\\_\\_node.selected_&]:shadow-lg',
className,
)}
tabIndex={0}
{...props}
/>
),
);
BaseNode.displayName = 'BaseNode';反馈
🌐 Feedback
我们希望这些改进能让你使用 React Flow UI 的体验更加出色。如果你有任何反馈或建议,请通过 邮件 或 Discord 告诉我们!
🌐 We hope these improvements make your experience with React Flow UI even better. If you have any feedback or suggestions, please let us know via mail or Discord !

学习部分重做
重新组织和更新内容
🌐 Restructured and updated content
我们已经查看并更新了我们的学习部分。以下是更改内容:
🌐 We went over and updated our learn section. Here’s what’s changed:
- 我们精简了大多数页面,并删除了一些我们认为没有助于更好理解库的内容。
- 快速启动现在是所有游戏的落地页面,负责安装和示例设置。
- 入门和概念已合并为一个部分。
- 自定义和概念部分已更新。我们的思路是通过按上下文缩短并清晰分隔页面,使它们在单独阅读和连续阅读时都易于理解。
- 在一般文本中,在我们的文档各部分之间包含了更多的互相链接,片段现在包括了高亮显示,并且布局和标题已经得到改进,以便更容易浏览文本。
重写代码预览
🌐 Reworked code preview
我们的代码预览组件已更新,采用了时尚的新设计,并配有一个操作栏,可让你切换、复制、刷新或在沙盒中打开代码。某些地方的默认大小也已调整,以更好地融入文本。它看起来是这样的:
🌐 Our code preview component has been updated with a sleek new design with an action bar that allows you to toggle, copy, refresh or open the code in a sandbox. The default size has also been adjusted in some places to integrate into the text better. Here’s what it looks like:

反馈
🌐 Feedback
我们希望这些改动能让你对 React Flow 的入门体验更加出色。如果你有反馈或建议,请通过 邮件 或 Discord 告诉我们!
🌐 We hope these changes make your introduction to React Flow even better. If you have feedback or suggestions, please let us know via mail or Discord !


React 流 12.7.1
补丁更改
🌐 Patch Changes
- #5354 添加 TSDoc 注释
- #5333 添加缺失的类型导出
- #5353 感谢 @aidanbarrett ! - 向
onReconnectEnd属性类型添加缺失的FinalConnectionState参数

React 流 12.7.0
此版本带来了一些改进,以提升可访问性以及更多功能:
🌐 This release comes with some improvements for a better accessibility and much more:
小幅更改
🌐 Minor Changes




React 流 12.5.5
补丁更改
🌐 Patch Changes
- #5172 感谢 @dimaMachina ! - 改进
useNodesData、useReactFlow、isNode和isEdge的 TSDoc 注释 - #5165 感谢 @dimaMachina ! - 改进
useViewport、useUpdateNodeInternals、useOnSelectionChange、useNodesInitialized钩子和UseOnSelectionChangeOptions、UseNodesInitializedOptions类型的 TSDoc 注释 - #5171 感谢 @dimaMachina ! - 改进
ReactFlowProps的 TSDoc 注释 - #5154 感谢 @ibagov ! - 改进
onNodesChange的 TSDoc 注释 - #5174 感谢 @dimaMachina ! - 改进
BaseEdgeProps的 TSDoc 注释 - #5159 感谢 @dimaMachina ! - 改进
useConnectionhook 的 TSDoc 注释 - #5167 感谢 @dimaMachina ! - 改进
useEdges、useInternalNode、useNodes和useNodeId钩子的 TSDoc 注释 - #5163 感谢 @dimaMachina ! - 改进
useNodesState和useEdgesState钩子的 TSDoc 注释 - #5160 感谢 @dimaMachina ! - 改进
type UseHandleConnectionsParams和useHandleConnections钩子的 TSDoc 注释 - #5162 感谢 @dimaMachina ! - 改进
type UseNodeConnectionsParams和useNodeConnections钩子的 TSDoc 注释 - #5164 感谢 @dimaMachina ! - 改进
type UseOnViewportChangeOptions和useOnViewportChange钩子的 TSDoc 注释 - #5166 感谢 @dimaMachina ! - 改进
useStore钩子的 TSDoc 注释 - #5170 感谢 @dimaMachina ! - 改进
interface GetSimpleBezierPathParams和getSimpleBezierPath的 TSDoc 注释 - #5161 感谢 @dimaMachina ! - 改进
type UseKeyPressOptions和useKeyPress钩子的 TSDoc 注释

React 流 12.5.0
fitView 变得更好了!
🌐 fitView just got a lot better!
你有没有在添加或更改节点后,让 fitView 正常工作时遇到困难?你的代码看起来像这样吗?
🌐 Have ever struggled with making fitView work right after adding or changing your nodes? Does your code look something like this?
setNodes((nodes) => [nodes, ...newNode]);
requestAnimationFrame(() => {
fitView();
});
// renders the node first and then fits the view :(好吧,你将会有一次愉快的体验!不再有漏洞,不再有 setTimeout 或 requestAnimationFrame,也不再有不匹配视图的瞬间帧!
🌐 Well, you are in for a treat! No more hacks, no more setTimeout or requestAnimationFrame and no more split second frames of unfitted views!
setNodes((nodes) => [nodes, ...newNode]);
fitView(); // it just works.
// adding a new node and fitting the view happens at the same time还有一件事
🌐 One more thing
你可能已经注意到,fitViewOptions 的 padding 值相当奇怪!padding: 0.3 究竟意味着什么?嗯,我们也不知道,所以你现在可以传递像素值 '25px'、视口百分比 '10%',真正的高手甚至可以
🌐 You might have realized that the padding value for fitViewOptions is quite a weird fella! What does padding: 0.3 even mean? Well we don’t know either, so you you can now pass pixel values '25px', viewport percentages '10%' and true pros can now even
const fitViewOptions = {
padding: {
/** horizontal */
x: '100px',
/** vertical */
y: '50px',
/** e.g. top overwrites x */
top: '25px',
/** mix and match units */
left: '15%',
/** legacy units still work */
bottom: 0.1,
/** have a modal on the right that stretches 50% over the screen? */
right: '50%',
},
};setNodes((nodes) => [nodes, ...newNode]);
fitView(); // it just works.
// adding a new node and fitting the view happens at the same time新功能
🌐 New Features
- #5067 为每一侧在 ‘px’ 或 ’%’ 中定义不同的 fitView 内边距。
补丁更改
🌐 Patch Changes
- #5067 修复在添加新节点后 fitView 无法立即生效的问题
- #5059 当连接进行中时,防止 onPaneClick 触发。
- #5093 隐藏节点不再显示在小地图上
- #5090 即使在输入输出字段聚焦时也释放按键
- 感谢 @dimaMachina !- 感谢你改进了
BackgroundProps、EdgeLabelOptions、ControlProps、NodeToolbarProps、EdgeLabelRendererProps、EdgeLabelOptions和EdgeTextProps的 TSDoc 注释

React 流 12.4.3
补丁更改
🌐 Patch Changes
- #5010 为组件、hooks、工具函数和类型添加更多 TSDocs
- #4991 感谢 @waynetee ! - 修复节点聚焦时视口移动的问题
- #5013 将
NodeType类型的参数从ReactFlowProps传递到connectionLineComponent属性。 - #5008 将 package.json 添加到导出中
- #5012 在 screenToFlowPosition 中添加 snapGrid 选项,并将 snapToGrid 设置为 false
- #5003 谢谢 @dimaMachina ! - 修复 lint 命令
- #4991 谢谢 @waynetee ! - 使用 Tab 后防止视口移动


React 流 12.4.0
新年,新的小版本发布 :) 这个版本主要包含修复,但也引入了一个新的 useNodeConnections,它是 useHandleConnections 的继任者。
🌐 New year, new minor release :) This release contains mostly fixes but also introduces a new useNodeConnections that is the successor of useHandleConnections.
小幅更改
🌐 Minor Changes
- #4725 添加
useNodeConnections钩子以跟踪与节点的所有连接。可以通过 handleType 和 handleId 进行筛选。
补丁更改
🌐 Patch Changes

React 流 12.3.6
补丁更改
🌐 Patch Changes
- #4846 使得可以在 immer 和其他不可变辅助工具中使用 expandParent
- #4865 向 BuiltInNode 类型添加组节点。感谢 @sjdemartini !
- #4877 修复了原点不是 [0,0] 的节点的交点。感谢 @gmvrpw !
- #4844 允许为 ReactFlow 组件自定义 data-testid
- #4816 通过传递 EdgeType 正确地为 isValidConnection 属性设置类型
- #4855 感谢 @mhuggins ! - 支持将
path元素属性传递给BaseEdge组件。 - #4862 当使用箭头键移动节点或选区时,防止默认滚动行为。
- #4875 在调整流程大小时防止边缘不必要的重新渲染。
- #4826 Panel 组件内部 div 的前向引用。

我们的例子焕然一新
我们已经重新设计了我们所有 React Flow 示例的样式。此外,我们还添加了一个新的主题文件,向你展示如何自定义你的流程的样式和交互。
🌐 We’ve revamped the styles across all our React Flow examples. Plus, we added a new theme file to show you how to customize the style and interactions of your flows.
我们认为它看起来非常棒,迫不及待想听听你的反馈。请查看下面我们更新的功能概览,以及我们所有其他更新的示例。
🌐 We think it looks fantastic and can’t wait to hear your feedback. Check out our updated Feature Overview below, along with all of our other updated examples.
import React, { useCallback } from 'react';
import {
ReactFlow,
addEdge,
MiniMap,
Controls,
Background,
useNodesState,
useEdgesState,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
nodes as initialNodes,
edges as initialEdges,
} from './initial-elements';
import AnnotationNode from './AnnotationNode';
import ToolbarNode from './ToolbarNode';
import ResizerNode from './ResizerNode';
import CircleNode from './CircleNode';
import TextInputNode from './TextInputNode';
import ButtonEdge from './ButtonEdge';
const nodeTypes = {
annotation: AnnotationNode,
tools: ToolbarNode,
resizer: ResizerNode,
circle: CircleNode,
textinput: TextInputNode,
};
const edgeTypes = {
button: ButtonEdge,
};
const nodeClassName = (node) => node.type;
const OverviewFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(params) => setEdges((eds) => addEdge(params, eds)),
[],
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
attributionPosition="top-right"
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
>
<MiniMap zoomable pannable nodeClassName={nodeClassName} />
<Controls />
<Background />
</ReactFlow>
);
};
export default OverviewFlow;

介绍 React Flow 组件 - 由 shadcn CLI 提供支持
我们一直对为 React Flow 开发可重复使用的组件感兴趣。随着最近 shadcn CLI 的发布,我们已经实现了这一目标!初始集合中的一些有趣组件包括:
🌐 We’ve been interested in developing reusable components for React Flow for a while now. With the recent releases of shadcn CLI, we’ve made that happen! Some interesting components from the initial set include:
- 一个数据库模式节点,使可视化表格和列之间的关系变得容易。
- 用于更方便地控制视口缩放级别的缩放滑块。
- 调试组件,使检查节点的属性和流程状态更容易。
我们很高兴看到你用这些组件构建的作品,并期待听到你的反馈!如果你遇到任何问题或对新组件有任何建议,请在我们的网络仓库 上提交问题,如果你用它们构建了很酷的东西,务必在Twitter上@xyflowdev @我们!
🌐 We’re excited to see what you build with these components, and we’re looking forward to hearing your feedback! Please open issues on our web repo if you run into any problems or have any suggestions for new components, and definitely tweet at us at @xyflowdev if you build something cool with them!
如果你想阅读完整的发布博客文章,你可以在 xyflow 博客的 这里 找到它。
🌐 If you want to read the entire release blog post, you can find it on the xyflow blog here .




我们已经更新了示例查看器!
很长一段时间以来,我们的示例都是建立在 Sandpack 之上的。这对我们来说是一个强大的工具,可以在文档中提供交互式示例,但这也带来了一定的代价。
🌐 For a long time now our examples have been built on top of Sandpack . This has been a powerful tool for us to provide interactive examples in our docs but it’s also come at a cost.
这些问题
🌐 The problems
我们喜欢 Sandpack,但我们不断遇到一些痛点,最终决定我们无法忽视这些问题。
🌐 We liked Sandpack, but we kept brushing up against some pain points that ultimately we decided we couldn’t ignore.
- 我们的示例加载很慢。 Sandpack 是一个令人印象深刻的工具,但它也是一个比较重的工具。Sandpack 客户端本身需要一些时间来加载,然后如果示例包含依赖,这些依赖也需要被获取。对于一次性的示例页面来说,这还不算太糟,但对于像我们的指南或教程这样较长的文档页面,这可能会真正打断用户的使用节奏。
- Sandpack 在我们首次发布 Svelte Flow 时并不完全支持 Svelte。最终,我们开发了一个单独的 SvelteKit 应用来托管我们的 Svelte 示例,并调整了我们的示例查看器,以便在 Sandpack 示例和简单的 iframe 嵌入之间切换。
- 最后,开发新的示例非常麻烦。 我们的 React 示例的源代码存放在示例查看器组件深处的文件夹中,并且对某些文件或格式有特殊处理,这使得编写示例变得相当困难:每次对示例的更改都会触发文档的热重载,这意味着要等待 Sandpack 重新加载并一次又一次地重新渲染示例。
而且除此之外,我们还有一个完全独立的应用,用于生成我们示例概览页面的截图!
🌐 And on top of all that we had an entirely separate app we used to generate the screenshots for our examples overview page!
解决方案
🌐 The solution
我们对我们的 Svelte 示例的工作方式感到非常满意(谢谢 Peter),并且决定我们想要探索一个统一的解决方案,可以同时适用于我们的 Svelte 和 React 示例。最终,我们得到了一个比我们的 SvelteKit 应用甚至更简单的方案,完全不需要服务器,而是从一个静态网站提供所有内容。
🌐 We were quite happy with how our Svelte examples worked (thank you Peter), and decided we wanted to explore a unified solution that would work for both our Svelte and React examples. In the end, we landed up with something even simpler than our SvelteKit app, dropping the need for a server entirely and instead serving everything from a static site.
我们在我们的 monorepo 中创建了一个单一的 example-apps 应用,该应用使用 vite 在开发期间提供我们的示例,并将它们构建为用于生产的静态文件。如果你感兴趣,你可以在 examples-apps.xyflow.com 找到我们所有示例的一个纯目录。
🌐 We’ve created a single example-apps app in our monorepo that uses vite to serve our examples during development and build them into static files for production. If you’re curious, you can find a plain directory of all our examples over at examples-apps.xyflow.com.
我们也使编写示例变得更容易。现在开发示例更类似于开发独立应用,我们还编写了一个简单的脚手架脚本,帮助我们快速创建新示例:
🌐 We also made authoring examples easier. Developing examples now more closely resembles developing a standalone app, and we put together a simple scaffold script to help us quickly create new examples:
The scaffold script helps you quickly put together a new example for either
reactflow.dev or svelteflow.dev by copying over the boilerplate. All arguments
are _required_.
USAGE:
pnpm scaffold <FRAMEWORK> <ROUTE>
EXAMPLES:
pnpm scaffold react blog/web-audio/demo
pnpm scaffold svelte guides/getting-started
ARGUMENTS:
FRAMEWORK 'react' | 'svelte'
The framework the example will be written in. This affects where
the generated files are placed in conjunction with the ROUTE
argument.
ROUTE string
The route fragment the example app will be served at when combined
with the FRAMEWORK argument. For example, calling the script as
`pnpm scaffold react examples/nodes/custom-node` will scaffold
the example and make it accessible at
'/react/examples/nodes/custom-node/index.html'.有没有什么缺点?
🌐 Are there any downsides?
在过渡期间,我们失去了一个重要功能:直接在文档网站上编辑示例的能力。对于一些用户来说,这可能是一个大问题,但作为补偿,我们现在除了支持 CodeSandbox 之外,还支持在 StackBlitz 中打开示例!
🌐 We’ve lost one big feature in the transition: the ability to edit examples directly on the docs site. For some users this might be a big deal, but to compensate we now support opening the examples in StackBlitz in addition to CodeSandbox!
结束
🌐 Wrap up
就这些了,大家 。对于大多数人来说,这次更改应该是无缝的,还能顺便提升性能。如果我们在迁移过程中弄坏了什么,请通过提交问题 告诉我们,如果你对这些更改感到兴奋,我们很希望你在推特上分享并标记我们@xyflowdev !



新的边缘示例
这里有一组关于新边的示例,包括如何沿边路径动画节点,如何创建临时边,以及每个连接事件的演示。我们希望这组新的示例能帮助你提升流程操作水平!
🌐 Here’s a care drop of new edge examples including how to animate nodes along an edge path, how to create temporary edges, and a demo of every connection event. We hope this new bundle of examples will help you level up your flow game!
import { useEffect, useMemo } from 'react';
import {
BaseEdge,
getBezierPath,
useReactFlow,
type Edge,
type EdgeProps,
} from '@xyflow/react';
export type AnimatedNodeEdge = Edge<{ node: string }, 'animatedNode'>;
export function AnimatedNodeEdge({
id,
data = { node: '' },
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
}: EdgeProps<AnimatedNodeEdge>) {
const { getNode, updateNode } = useReactFlow();
const [edgePath] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
});
const selector = useMemo(
() => `.react-flow__node[data-id="${data.node}"]`,
[data.node],
);
useEffect(() => {
const node = document.querySelector(selector) as HTMLElement;
if (!node) return;
node.style.offsetPath = `path('${edgePath}')`;
node.style.offsetRotate = '0deg';
// This property is fairly new and not all versions of TypeScript have it
// in the lib.dom.d.ts file. If you get an error here, you can either
// ignore it or add the property to the CSSStyleDeclaration interface
// yourself.
//
// @ts-expect-error
node.style.offsetAnchor = 'center';
let wasDraggable = getNode(data.node).draggable;
updateNode(data.node, { draggable: false });
return () => {
node.style.offsetPath = 'none';
updateNode(data.node, { draggable: wasDraggable });
};
}, [selector, edgePath]);
useEffect(() => {
const node = document.querySelector(selector) as HTMLElement;
if (!node) return;
const keyframes = [{ offsetDistance: '0%' }, { offsetDistance: '100%' }];
const animation = node.animate(keyframes, {
duration: 2000,
direction: 'alternate',
iterations: Infinity,
});
return () => {
animation.cancel();
};
}, [selector]);
return <BaseEdge id={id} path={edgePath} />;
}这是新增内容的详细分解:
🌐 This is a breakdown of what’s been added:

新教程 – 使用 React Flow 创建幻灯片演示文稿
我们最近发布了 React Flow 2023 年年终调查的结果,并提供了一个 互动演示 来展示主要发现,该演示本身是使用 React Flow 制作的。这个幻灯片应用内包含了许多有用的功能,所以我们想分享一下我们是如何构建它的!
🌐 We recently published the findings from our React Flow 2023 end-of-year survey with an interactive presentation of the key findings, using React Flow itself. There were lots of useful bits built into this slideshow app, so we wanted to share how we built it!

新版本 12.0.0
React Flow 12 终于发布了!带有一个新的包名 @xyflow/react!
🌐 React Flow 12 is finally out! With a new package name @xyflow/react!
主要特点
🌐 Main features
- SSR / SSG: 你可以为节点定义
width、height和handles。这使得可以在服务器上渲染流程,并在客户端进行 hydrate:SSR 指南- 详情:在 v11 中,一旦节点被测量,库就会设置
width和height。这种情况仍然发生,但我们现在使用measured.width和measured.height来存储这些信息。在先前的版本中,关于width和height总是存在很多混淆。很难理解的是,你不能用它来传递实际的宽度或高度。也不是很明显这些属性是由库添加的。我们认为新的实现解决了这两个问题:width和height是可选属性,可用于定义尺寸,而测量后的尺寸存储在measured中。
- 详情:在 v11 中,一旦节点被测量,库就会设置
- 反应流: 新的钩子
useHandleConnections和useNodesData以及新的updateNode和updateNodeData函数可以用于管理节点之间的数据流:计算流指南- 详情:处理响应式流非常常见。你更新节点 A,并希望在连接的节点 B 上对这些变化做出反应。直到现在,每个人都必须自己想出一个自定义解决方案。通过这个版本,我们希望改变这一点,并为你提供高效的辅助工具来处理它。如果你对此感到兴奋,可以查看这个示例:
- 夜间模式和 CSS 变量: React Flow 现在带有内置的夜间模式,可以通过使用新的
colorMode属性(“light”、“dark” 或 “system”)来切换:夜间模式示例- 详情:在此版本中,我们希望让切换深色和浅色模式更加容易,并为深色流程提供一个更好的起点。如果你传入 colorMode=“dark”,我们会在封装器上添加类名“dark”,并用它来调整样式。为了让我们更容易实现这个新功能,我们将大部分样式切换为使用 CSS 变量。这些变量也可以在用户端用于自定义流程。
更多功能和更新
🌐 More features and updates
还有更多!除了新的主要功能外,我们还添加了一些在我们的清单上已经很久的小功能。我们还开始使用 TS 文档来改善文档质量。我们已经开始为一些类型和 hooks 添加文档,这应该会提升开发者体验。
🌐 There is more! Besides the new main features, we added some minor things that were on our list for a long time. We also started to use TS docs for better docs. We already started to add some docs for some types and hooks which should improve the developer experience.
useConnection钩子: 使用此钩子,你可以访问正在进行的连接。例如,你可以使用它为句柄上色,或者根据当前的起始/结束句柄自定义连接线的样式。- 受控
viewport: 这是一个高级功能。可能的使用场景包括动画化视口或对低分辨率屏幕进行变换圆整等。该功能带来了两个新属性:viewport和onViewportChange。 ViewportPortal组件: 这使得可以在视口中渲染元素,而无需实现自定义节点。onDelete处理程序:我们添加了一个用于onDeleteNodes和onDeleteEdges的组合处理程序,以便更容易地对删除操作做出反应。onBeforeDelete处理程序:使用此处理程序,你可以防止/管理删除。isValidConnection属性: 这使得为所有连接实现一个验证函数成为可能。它也会在程序matically添加的边上被调用。autoPanSpeed属性: 用于控制自动平移时的速度。- 背景组件:添加
patternClassName属性,以便能够通过使用类名来设置背景图案的样式。例如,如果你想使用 Tailwind 来设置背景图案的样式,这会很有用。 onMove回调 会在库调用的视口更新(例如 fitView 或 zoom-in)时触发deleteElements现在返回已删除的节点和已删除的边- 为节点添加
origin属性 - 为边添加
selectable属性 - 节点调整器:当组调整大小时,子节点不会移动,范围和展开被正确识别
BezierEdge、StepEdge、SmoothStepEdge和StraightEdge组件的正确类型- 库创建的新边只有在设置了这些属性时才会有
sourceHandle和targetHandle属性。(我们以前会传递sourceHandle: null和targetHandle: null) - 当 z 索引更改时,边不会挂载/卸载
- 连接线知道目标句柄的位置,以便路径被正确绘制
nodeDragThreshold默认是 1,而不是 0- 更好的选择框可用性(拖出流程时捕获)
- 将
selectable、deletable、draggable和parentId添加到NodeProps - 当样式未加载时添加警告

Entitree Flex 布局示例
我们通过添加 Entitree Flex 为我们的示例阵容增加了一个新的布局算法。该算法类似于 d3-hierarchy,但允许使用兄弟节点以及具有不同尺寸的节点。
🌐 We add a new layouting algorithm to our example lineup with the addition of Entitree Flex. This algorithm is similar to d3-hierarchy but allows for sibling nodes as well as nodes with different dimensions.
这个示例由 GitHub 用户 @kaustubhxd 非常友好地提供,感谢 Kaustubh!请在下面查看。
🌐 This example was very kindly contributed by GitHub user @kaustubhxd , thanks Kaustubh! Check it out below.
import React, { useCallback } from 'react';
import {
Background,
ReactFlow,
addEdge,
ConnectionLineType,
Panel,
useNodesState,
useEdgesState,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import CustomNode from './CustomNode';
import { initialTree, treeRootId } from './initialElements';
import { layoutElements } from './layout-elements';
const nodeTypes = {
custom: CustomNode,
};
const { nodes: layoutedNodes, edges: layoutedEdges } = layoutElements(
initialTree,
treeRootId,
'TB',
);
const LayoutFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(layoutedNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges);
const onConnect = useCallback(
(params) =>
setEdges((eds) =>
addEdge({ ...params, type: ConnectionLineType.SmoothStep, animated: true }, eds),
),
[],
);
const onLayout = useCallback(
(direction) => {
const { nodes: layoutedNodes, edges: layoutedEdges } = layoutElements(
initialTree,
treeRootId,
direction,
);
setNodes([...layoutedNodes]);
setEdges([...layoutedEdges]);
},
[nodes, edges],
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
connectionLineType={ConnectionLineType.SmoothStep}
fitView
nodeTypes={nodeTypes}
>
<Panel position="top-right">
<button className="xy-theme__button" onClick={() => onLayout('TB')}>
vertical layout
</button>
<button className="xy-theme__button" onClick={() => onLayout('LR')}>
horizontal layout
</button>
</Panel>
<Background />
</ReactFlow>
);
};
export default LayoutFlow;
开发工具和一个新的概览示例
有时很难理解你的 React Flow 应用中发生了什么。这就是为什么我们在文档中添加了一个 开发者工具部分。这是一个可复制粘贴的示例,解释了如何获取你 React Flow 应用的一些见解。我们还发布了功能概览示例的修订版。
🌐 Sometimes it’s hard to understand what’s going on in your React Flow app. That’s why we’ve added a devtools section to the docs. It’s a copy pastable example that explains how you can get some insights into your React Flow app. We also published a revised version of the feature overview example.
在下面查看吧!
🌐 Check it out below!
import React, { useCallback } from 'react';
import {
ReactFlow,
addEdge,
MiniMap,
Controls,
Background,
useNodesState,
useEdgesState,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
nodes as initialNodes,
edges as initialEdges,
} from './initial-elements';
import AnnotationNode from './AnnotationNode';
import ToolbarNode from './ToolbarNode';
import ResizerNode from './ResizerNode';
import CircleNode from './CircleNode';
import TextInputNode from './TextInputNode';
import ButtonEdge from './ButtonEdge';
const nodeTypes = {
annotation: AnnotationNode,
tools: ToolbarNode,
resizer: ResizerNode,
circle: CircleNode,
textinput: TextInputNode,
};
const edgeTypes = {
button: ButtonEdge,
};
const nodeClassName = (node) => node.type;
const OverviewFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(params) => setEdges((eds) => addEdge(params, eds)),
[],
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
attributionPosition="top-right"
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
>
<MiniMap zoomable pannable nodeClassName={nodeClassName} />
<Controls />
<Background />
</ReactFlow>
);
};
export default OverviewFlow;

我们终于做出了一个可编辑的 Edge Pro 示例
我们从用户那里收到的最常见问题之一是如何让用户编辑边的路径。这个 Pro 示例展示了如何做到这一点,通过将边切分成可以自由移动的段。
🌐 One of the most common questions we get from users is how to let users edit an edge’s path. This Pro example demonstrates how to do exactly that, by cutting up an edge into segments that can be freely moved around.
我们希望大家能找到这个例子,并使用相同的技术来实现诸如自由边缘绘制或算法边缘路由等功能。
🌐 We hope folks will find this example and use the same technique to implement features like freeform edge drawing or algorithmic edge routing.
This is a Pro example. Get all pro examples, templates, 1:1 support from the xyflow team and prioritized Github issues with a React Flow Pro subscription.

React Flow 12 终于来了
React Flow 12 终于来了 我们非常兴奋,并希望你像我们一样享受这些新功能。版本 12 的重点内容有:
- 支持 SSG/SSR:你现在可以在服务器上渲染流程
- 计算流:用于简化数据流的新钩子和辅助函数
- 暗黑模式:一种新的基础样式和在内置颜色模式之间切换的简便方法
- 使用 TSDoc 改善开发者体验:我们添加了 TSDoc 来提升开发者体验
如果你想从 11 迁移到 12 或查看 新功能,请参考 迁移指南。
🌐 If you want to migrate from 11 to 12 or check out the new features, please refer to the migration guide.

新的多连接线路示例!
很久以前,有一位用户在GitHub问题 中提出希望我们为库添加绘制多条连接线的功能。我们目前没有将其添加到库本身的计划,但我们希望这个示例能帮助需要在自己应用中实现此功能的人。请在这里查看。
🌐 Quite a while back, a user opened a GitHub issue asking us to add the ability to draw multiple connection lines to the library. We don’t have any plans to add this to the library itself, but we hope this example helps folks who need this functionality in their own apps. Check it out here.
import { useCallback } from 'react';
import {
ReactFlow,
Background,
useNodesState,
useEdgesState,
addEdge,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import ConnectionLine from './ConnectionLine';
const initialNodes = [
{
id: 'a',
type: 'input',
data: { label: 'Click to select' },
position: { x: 100, y: -100 },
},
{
id: 'b',
type: 'input',
data: { label: 'these nodes' },
position: { x: 300, y: -50 },
},
{
id: 'c',
type: 'input',
data: { label: 'then drag... ' },
position: { x: 150, y: 0 },
},
{
id: 'd',
type: 'output',
data: { label: '...and connect to me!' },
position: { x: 250, y: 200 },
},
];
const ConnectionLineFlow = () => {
const [nodes, _, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const onConnect = useCallback(
({ source, target }) => {
return setEdges((eds) =>
nodes
.filter((node) => node.id === source || node.selected)
.reduce(
(eds, node) => addEdge({ source: node.id, target }, eds),
eds,
),
);
},
[nodes],
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
connectionLineComponent={ConnectionLine}
onConnect={onConnect}
fitView
fitViewOptions={{
padding: 0.2,
}}
>
<Background />
</ReactFlow>
);
};
export default ConnectionLineFlow;
新的 ELKjs 示例!
我们为 ELKjs 的更高级用法添加了一个新示例,展示如何将其与具有多个句柄的节点一起使用。正如你在示例中看到的,ELKjs 会自动处理边的交叉,并且节点会在句柄位置的帮助下进行排序。请在这里查看。
🌐 We added a new example for a more advanced usage of ELKjs to show how to use it with nodes with multiple handles. As you can see in the example, edge crossing is handled automatically by ELKjs and the nodes are ordered with help of the handle position. Check it out here.

新节点工具栏示例!
在我们的 API 参考中隐藏着我们的 <NodeToolbar /> 组件的文档。不过我们一直缺少一个示例来配合它,因此我们发布了一个新的示例来展示它的使用方法。在这里查看 链接。
🌐 Buried away in our API reference is the documentation for our
<NodeToolbar /> component. We’ve been missing
an example to accompany it though, so we’ve published a new example to show how
it can be used. Check it out here.
import { useCallback } from 'react';
import {
Background,
ReactFlow,
ReactFlowProvider,
Panel,
NodeToolbar,
Position,
useNodesState,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const initialNodes = [
{
id: '1',
position: { x: 0, y: 0 },
type: 'node-with-toolbar',
data: { label: 'Select me to show the toolbar' },
},
];
const nodeTypes = {
'node-with-toolbar': NodeWithToolbar,
};
function NodeWithToolbar({ data }) {
return (
<>
<NodeToolbar
isVisible={data.forceToolbarVisible || undefined}
position={data.toolbarPosition}
align={data.align}
>
<button className="xy-theme__button">cut</button>
<button className="xy-theme__button">copy</button>
<button className="xy-theme__button">paste</button>
</NodeToolbar>
<div>{data?.label}</div>
</>
);
}
function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const setPosition = useCallback(
(pos) =>
setNodes((nodes) =>
nodes.map((node) => ({
...node,
data: { ...node.data, toolbarPosition: pos },
})),
),
[setNodes],
);
const setAlignment = useCallback(
(align) =>
setNodes((nodes) =>
nodes.map((node) => ({
...node,
data: { ...node.data, align },
})),
),
[setNodes],
);
const forceToolbarVisible = useCallback((enabled) =>
setNodes((nodes) =>
nodes.map((node) => ({
...node,
data: { ...node.data, forceToolbarVisible: enabled },
})),
),
);
return (
<ReactFlowProvider>
<ReactFlow
nodes={nodes}
onNodesChange={onNodesChange}
nodeTypes={nodeTypes}
fitView
preventScrolling={false}
>
<Panel>
<h3>Node Toolbar position:</h3>
<button className="xy-theme__button" onClick={() => setPosition(Position.Top)}>
top
</button>
<button
className="xy-theme__button"
onClick={() => setPosition(Position.Right)}
>
right
</button>
<button
className="xy-theme__button"
onClick={() => setPosition(Position.Bottom)}
>
bottom
</button>
<button className="xy-theme__button" onClick={() => setPosition(Position.Left)}>
left
</button>
<h3>Node Toolbar Alignment:</h3>
<button className="xy-theme__button" onClick={() => setAlignment('start')}>
start
</button>
<button className="xy-theme__button" onClick={() => setAlignment('center')}>
center
</button>
<button className="xy-theme__button" onClick={() => setAlignment('end')}>
end
</button>
<h3>Override Node Toolbar visibility</h3>
<label>
<input
type="checkbox"
onChange={(e) => forceToolbarVisible(e.target.checked)}
className="xy-theme__checkbox"
/>
<span>Always show toolbar</span>
</label>
</Panel>
<Background />
</ReactFlow>
</ReactFlowProvider>
);
}
export default Flow;

首届年度 React Flow 开发者调查启动!
我们已经做这个 React Flow 的事情有一段时间了,通过 GitHub 上的问题和我们 Discord 服务器 上的讨论,我们学到了很多关于用户希望和需要从这个库中获得什么的内容。不过,要了解人们对我们文档的体验,或者从大量可能并未积极参与我们社区的用户那里获得反馈,要困难得多。
🌐 We’ve been doing this React Flow thing for a while now and between issues on GitHub and conversations on our Discord server , we’ve learned a lot about what our users want and need from the library. It’s a lot harder to hear about people’s experience with our docs or from the large number of users that might not be actively taking part in our communities, though.
过去,我们曾安排与一些专业订阅用户进行访谈,以了解他们如何使用 React Flow 和专业平台,并发现这些见解非常宝贵。今年,我们希望将这一范围扩大到尽可能多的用户,因此我们准备了一份简短的调查问卷,以帮助我们在新的一年中确定发展方向。
🌐 In the past we’ve arranged interviews with some of our Pro subscribers to get an idea of how they use React Flow and the Pro Platform and found the insight invaluable. This year we want to expand that to include as many of our users as possible, so we’ve put together a short survey to help steer our direction going into the new year.
完成它只需要几分钟,如果你能抽出时间填写,我们将不胜感激。你可以在这里找到问卷,我们将在新年初公布结果!
🌐 It should only take a few minutes to complete and we’d really appreciate it if you could find the time to fill it out. You can find the survey here and we’ll be publishing the results early in the new year!


React Flow Pro 平台开源了!

我们通过 React Flow Pro 订阅为我们的开源库提供资金支持。订阅者可以访问我们的专业平台,在那里他们可以查看高级示例、联系我们获取一对一支持,并帮助我们确定 GitHub 问题的优先级。到目前为止,这些代码一直是私有的,但我们已经从头重建了它,添加了功能,刷新了设计,并赋予了它应有的 MIT 许可证。
🌐 We fund our open source libraries with React Flow Pro subscriptions. Subscribers get access to our Pro Platform where they can view advanced examples, contact us for 1:1 support, and help us prioritize GitHub issues. So far that code has been private but we’ve rebuilt it from the ground-up, added features, refreshed the design, and gave it the MIT License it deserves.
目前它还不是即插即用的,但我们希望有些人会看看,从中获得自己项目的灵感,并且我们的专业订阅用户会喜欢我们开发的新功能。
🌐 It’s not plug-and-play at the moment, but we hope that some folks take a look, get inspired for their own projects, and that our Pro Subscribers like the new features we built.

新的自定义边缘指南!
我们添加了一份新指南,向大家展示如何创建自己的自定义边。该指南分解了<BaseEdge />和<EdgeLabelRenderer />组件的用途,并展示了如何使用 React Flow 提供的一些path utilities。
🌐 We’ve added a new guide to show folks how to create their own custom edges. This
guide breaks down what the <BaseEdge />
and <EdgeLabelRenderer />
components are for, and shows how to use some of the
path utilities React Flow provides.
你可以在我们的学习资源的自定义部分查看它 这里。
🌐 You can check it out in the customization section of our learning resources here.

新版本 11.10.0!
我们希望 v12 的迁移尽可能顺利。这就是为什么我们为以下工具函数添加了弃用警告的原因:
🌐 We want to make the migration for v12 as smooth as possible. That’s why we added deprecation warnings for the following util functions:
将 useReactFlow.project 重命名为 useReactFlow.screenToFlowPosition
🌐 Rename useReactFlow.project to useReactFlow.screenToFlowPosition
⚠️ 更改:不再需要减去 React Flow 的边界!
before:
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
const position = reactFlowInstance.project({
x: event.clientX - reactFlowBounds.left,
y: event.clientY - reactFlowBounds.top,
});after:
const position = reactFlowInstance.screenToFlowPosition({
x: event.clientX,
y: event.clientY,
});将 getTransformForBounds 重命名为 getViewportForBounds
🌐 Rename getTransformForBounds to getViewportForBounds
⚠️ 更改:返回 { x: number, y: number, zoom: number } 而不是 [number, number, number]。
before:
const [x, y, zoom] = getTransformForBounds(bounds, width, height, 0.5, 2);after:
const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2);将 getRectOfNodes 重命名为 getNodesBounds
🌐 Rename getRectOfNodes to getNodesBounds
没有变化,只是改名。
🌐 no changes, just a renaming.
新功能
🌐 New features
- 添加了
useReactFlow.flowToScreenPosition以完成
除此之外,我们修复了一些错误 🐛 你可以在 v11.10.0 Github 发布 中找到所有更改。
🌐 Besides that we fixed some bugs 🐛 You can find all change in the v11.10.0 Github release .

新的“防止连接循环”示例!
“防止连接循环”示例展示了如何使用getOutgoers工具来检查新的连接是否会在流程中造成循环。在这里查看:here。
🌐 The “Prevent connection cycles” example shows how to use the
getOutgoers util to check if a new
connection would cause a cycle in the flow. Check it out here.
import React, { useCallback } from 'react';
import {
ReactFlow,
Background,
useNodesState,
useEdgesState,
addEdge,
getOutgoers,
useReactFlow,
ReactFlowProvider,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
nodes as initialNodes,
edges as initialEdges,
} from './initialElements';
const Flow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const { getNodes, getEdges } = useReactFlow();
const isValidConnection = useCallback(
(connection) => {
// we are using getNodes and getEdges helpers here
// to make sure we create isValidConnection function only once
const nodes = getNodes();
const edges = getEdges();
const target = nodes.find((node) => node.id === connection.target);
const hasCycle = (node, visited = new Set()) => {
if (visited.has(node.id)) return false;
visited.add(node.id);
for (const outgoer of getOutgoers(node, nodes, edges)) {
if (outgoer.id === connection.source) return true;
if (hasCycle(outgoer, visited)) return true;
}
};
if (target.id === connection.source) return false;
return !hasCycle(target);
},
[getNodes, getEdges],
);
const onConnect = useCallback((params) =>
setEdges((els) => addEdge(params, els)),
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
isValidConnection={isValidConnection}
fitView
>
<Background />
</ReactFlow>
);
};
export default () => (
<ReactFlowProvider>
<Flow />
</ReactFlowProvider>
);
我们更新了我们的文档!
我们在2023年11月刷新了React Flow文档,所以这里的内容可能看起来有些不同:
🌐 We refreshed the React Flow docs in November 2023, so things might look a little different around here:
- 文档现在称为 学习。本部分旨在回答“我如何使用 X?”这个问题。
- API 现在称为 Reference。本节回答“这是什么东西?”这个问题。与我们之前版本的文档相比,一个重大变化是我们所有的类型、组件、hooks 和工具函数现在都有了自己的页面。
- “如何做”博客文章现在位于 学习 > 教程
为什么会有这些变化?
🌐 Why the changes?
到目前为止,自2019年以来,文档一直在自然增长,并没有任何总体的概念。在我们进行网站重新设计的同时,我们决定是时候重新思考大家如何使用我们的文档,以便我们能够创建更好的开发者体验。我们希望这些更改能让文档对有经验的 React Flow 用户和新手都更易于使用。
🌐 So far the docs have been growing organically since 2019, without any sort of overarching concept. While we worked on a website redesign, we decided it was time to rethink how folks are using our docs so that we can create a better developer experience. Our hope is that these changes make the docs easier to use for both experienced React Flow users and newcomers.
我们在过程中也更换了技术栈。我们之前使用 Docusaurus,现在我们使用 Nextra 。很棒。
🌐 We also did a change of tech stack along the way. We were using Docusaurus, and now we’re using Nextra . Cool beans.
如果你发现任何需要更改或改进的地方,只需点击我们文档中任意页面右侧的“编辑此页面”链接,或者在GitHub 上提交一个问题。
🌐 If you find anything to change or improve, just click on the “Edit this page” link on the right-side of any page in our docs or open an issue over on GitHub .