Skip to content

Commit cb45f2c

Browse files
tomas-cprevwong
authored andcommitted
feat: SSR support (#637)
1 parent 1212856 commit cb45f2c

File tree

4 files changed

+27
-35
lines changed

4 files changed

+27
-35
lines changed

.changeset/real-glasses-cross.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@craftjs/core': patch
3+
---
4+
5+
SSR support

packages/core/src/nodes/Element.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ERROR_TOP_LEVEL_ELEMENT_NO_ID, useEffectOnce } from '@craftjs/utils';
1+
import { ERROR_TOP_LEVEL_ELEMENT_NO_ID } from '@craftjs/utils';
22
import React, { useState } from 'react';
33
import invariant from 'tiny-invariant';
44

@@ -47,9 +47,7 @@ export function Element<T extends React.ElementType>({
4747
},
4848
}));
4949

50-
const [linkedNodeId, setLinkedNodeId] = useState<NodeId | null>(null);
51-
52-
useEffectOnce(() => {
50+
const [linkedNodeId] = useState<NodeId | null>(() => {
5351
invariant(!!id, ERROR_TOP_LEVEL_ELEMENT_NO_ID);
5452
const { id: nodeId, data } = node;
5553

@@ -77,9 +75,9 @@ export function Element<T extends React.ElementType>({
7775
linkedNodeId = tree.rootNodeId;
7876
actions.history.ignore().addLinkedNodeFromTree(tree, nodeId, id);
7977
}
80-
81-
setLinkedNodeId(linkedNodeId);
78+
return linkedNodeId;
8279
}
80+
return null;
8381
});
8482

8583
return linkedNodeId ? <NodeElement id={linkedNodeId} /> : null;

packages/core/src/nodes/tests/Element.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ describe('<Element />', () => {
7979
});
8080

8181
it('should call query.parseReactElement()', () => {
82-
expect(parseReactElement).toHaveBeenCalledWith(
82+
const arg0 = parseReactElement.mock.calls[0][0];
83+
const arg0WithoutOwner = { ...arg0, _owner: null };
84+
expect(arg0WithoutOwner).toEqual(
8385
<Element {...elementProps}>{children}</Element>
8486
);
8587
});

packages/core/src/render/Frame.tsx

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { deprecationWarning, ROOT_NODE } from '@craftjs/utils';
2-
import React, { useEffect, useRef } from 'react';
2+
import React, { useRef } from 'react';
33

44
import { useInternalEditor } from '../editor/useInternalEditor';
55
import { SerializedNodes } from '../interfaces';
@@ -39,41 +39,28 @@ export const Frame: React.FC<React.PropsWithChildren<FrameProps>> = ({
3939
});
4040
}
4141

42-
const initialState = useRef({
43-
initialChildren: children,
44-
initialData: data || json,
45-
});
42+
const isLoaded = useRef(false);
4643

47-
const isInitialChildrenLoadedRef = useRef(false);
48-
49-
useEffect(() => {
50-
const { initialChildren, initialData } = initialState.current;
44+
if (!isLoaded.current) {
45+
const initialData = data || json;
5146

5247
if (initialData) {
5348
actions.history.ignore().deserialize(initialData);
54-
return;
55-
}
49+
} else if (children) {
50+
const rootNode = React.Children.only(children) as React.ReactElement;
5651

57-
// Prevent recreating Nodes from child elements if we already did it the first time
58-
// Usually an issue in React Strict Mode where this hook is called twice which results in orphaned Nodes
59-
const isInitialChildrenLoaded = isInitialChildrenLoadedRef.current;
52+
const node = query.parseReactElement(rootNode).toNodeTree((node, jsx) => {
53+
if (jsx === rootNode) {
54+
node.id = ROOT_NODE;
55+
}
56+
return node;
57+
});
6058

61-
if (!initialChildren || isInitialChildrenLoaded) {
62-
return;
59+
actions.history.ignore().addNodeTree(node);
6360
}
6461

65-
const rootNode = React.Children.only(initialChildren) as React.ReactElement;
66-
67-
const node = query.parseReactElement(rootNode).toNodeTree((node, jsx) => {
68-
if (jsx === rootNode) {
69-
node.id = ROOT_NODE;
70-
}
71-
return node;
72-
});
73-
74-
actions.history.ignore().addNodeTree(node);
75-
isInitialChildrenLoadedRef.current = true;
76-
}, [actions, query]);
62+
isLoaded.current = true;
63+
}
7764

7865
return <RenderRootNode />;
7966
};

0 commit comments

Comments
 (0)