diff --git a/packages/site/common/react-snippet-strict.md b/packages/site/common/react-snippet-strict.md
index cc3ee6b3f1b..7dd51d9ec7a 100644
--- a/packages/site/common/react-snippet-strict.md
+++ b/packages/site/common/react-snippet-strict.md
@@ -1,47 +1,75 @@
```tsx
-import type { GraphOptions } from '@antv/g6';
-import { Graph as G6Graph } from '@antv/g6';
+import { ExtensionCategory, Graph as G6Graph, register } from '@antv/g6';
+import { ReactNode } from '@antv/g6-extension-react';
import { useEffect, useRef } from 'react';
-export interface GraphProps {
- options: GraphOptions;
- onRender?: (graph: G6Graph) => void;
- onDestroy?: () => void;
-}
+register(ExtensionCategory.NODE, 'react-node', ReactNode);
+
+const SelectableNode = (props: { selected: boolean; onToggle: () => void }) => {
+ const { selected, onToggle } = props;
+
+ return (
+
+ );
+};
-export const Graph = (props: GraphProps) => {
- const { options, onRender, onDestroy } = props;
- const graphRef = useRef();
+export default function App() {
const containerRef = useRef(null);
+ const graphRef = useRef(null);
useEffect(() => {
- const graph = new G6Graph({ container: containerRef.current! });
- graphRef.current = graph;
+ if (!containerRef.current) return;
- return () => {
+ const handleToggle = (id: string, selected: boolean) => {
const graph = graphRef.current;
- if (graph) {
- graph.destroy();
- onDestroy?.();
- graphRef.current = undefined;
- }
+ if (!graph) return;
+
+ graph.updateNodeData([{ id, data: { selected: !selected } }]);
+ graph.draw();
};
- }, []);
- useEffect(() => {
- const container = containerRef.current;
- const graph = graphRef.current;
+ const graph = new G6Graph({
+ container: containerRef.current,
+ width: 500,
+ height: 300,
+ data: {
+ nodes: [{ id: 'node-1', style: { x: 250, y: 150 }, data: { selected: false } }],
+ },
+ node: {
+ type: 'react-node',
+ style: {
+ size: [160, 50],
+ component: (data) => (
+ handleToggle(data.id, Boolean(data.data?.selected))}
+ />
+ ),
+ },
+ },
+ });
- if (!options || !container || !graph || graph.destroyed) return;
+ graphRef.current = graph;
+ graph.render();
- graph.setOptions(options);
- graph
- .render()
- .then(() => onRender?.(graph))
- // eslint-disable-next-line no-console
- .catch((error) => console.debug(error));
- }, [options]);
+ return () => {
+ graph.destroy();
+ graphRef.current = null;
+ };
+ }, []);
- return ;
-};
+ return ;
+}
```
diff --git a/packages/site/docs/manual/getting-started/integration/react.en.md b/packages/site/docs/manual/getting-started/integration/react.en.md
index b1e88bfc914..2932bf02f1e 100644
--- a/packages/site/docs/manual/getting-started/integration/react.en.md
+++ b/packages/site/docs/manual/getting-started/integration/react.en.md
@@ -11,6 +11,6 @@ Refer to the example below, you can use G6 in React, and you can also view the [
## Strict Mode
-In strict mode, React will update twice, causing G6 to create and destroy the Graph instance repeatedly. You can refer to the following example to solve this problem:
+In strict mode, React intentionally mounts, unmounts, and remounts components in development. Create the Graph instance inside an effect, keep it in a ref, and destroy it in the cleanup callback so the first development-only mount does not leave a stale graph behind. The following complete example also shows how to register and render a React node.
diff --git a/packages/site/docs/manual/getting-started/integration/react.zh.md b/packages/site/docs/manual/getting-started/integration/react.zh.md
index 97e47da199f..97af194eeba 100644
--- a/packages/site/docs/manual/getting-started/integration/react.zh.md
+++ b/packages/site/docs/manual/getting-started/integration/react.zh.md
@@ -15,6 +15,6 @@ order: 0
## 严格模式
-在严格模式下,React 会二次更新导致 G6 重复创建 Graph 实例并销毁,可以参考如下示例解决:
+在严格模式下,React 会在开发环境中有意执行挂载、卸载、再挂载。请把 Graph 实例放在 effect 里创建,用 ref 保存,并在清理函数中销毁,这样第一次开发态挂载不会留下旧实例。下面的完整示例同时演示了如何注册和渲染 React 节点。