diff --git a/.changeset/grumpy-shrimps-call.md b/.changeset/grumpy-shrimps-call.md
new file mode 100644
index 000000000..3471cf5fc
--- /dev/null
+++ b/.changeset/grumpy-shrimps-call.md
@@ -0,0 +1,5 @@
+---
+'@craftjs/core': patch
+---
+
+Fix hydration errror in react strict mode
diff --git a/packages/core/src/nodes/Element.tsx b/packages/core/src/nodes/Element.tsx
index 8db7f4f6e..22b369e1f 100644
--- a/packages/core/src/nodes/Element.tsx
+++ b/packages/core/src/nodes/Element.tsx
@@ -40,42 +40,33 @@ export function Element({
};
const { query, actions } = useInternalEditor();
- const { node, inNodeContext } = useInternalNode((node) => ({
- node: {
- id: node.id,
- data: node.data,
- },
- }));
+ const { id: nodeId, inNodeContext } = useInternalNode();
const [linkedNodeId] = useState(() => {
invariant(!!id, ERROR_TOP_LEVEL_ELEMENT_NO_ID);
- const { id: nodeId, data } = node;
+ const node = query.node(nodeId).get();
if (inNodeContext) {
- let linkedNodeId;
-
- const existingNode =
- data.linkedNodes &&
- data.linkedNodes[id] &&
- query.node(data.linkedNodes[id]).get();
+ const existingNode = node.data.linkedNodes[id]
+ ? query.node(node.data.linkedNodes[id]).get()
+ : null;
// Render existing linked Node if it already exists (and is the same type as the JSX)
if (existingNode && existingNode.data.type === is) {
- linkedNodeId = existingNode.id;
- } else {
- // otherwise, create and render a new linked Node
- const linkedElement = React.createElement(
- Element,
- elementProps,
- children
- );
+ return existingNode.id;
+ }
- const tree = query.parseReactElement(linkedElement).toNodeTree();
+ // otherwise, create and render a new linked Node
+ const linkedElement = React.createElement(
+ Element,
+ elementProps,
+ children
+ );
- linkedNodeId = tree.rootNodeId;
- actions.history.ignore().addLinkedNodeFromTree(tree, nodeId, id);
- }
- return linkedNodeId;
+ const tree = query.parseReactElement(linkedElement).toNodeTree();
+
+ actions.history.ignore().addLinkedNodeFromTree(tree, nodeId, id);
+ return tree.rootNodeId;
}
return null;
});
diff --git a/packages/core/src/nodes/tests/Element.test.tsx b/packages/core/src/nodes/tests/Element.test.tsx
deleted file mode 100644
index a1d72f1b3..000000000
--- a/packages/core/src/nodes/tests/Element.test.tsx
+++ /dev/null
@@ -1,122 +0,0 @@
-import { render } from '@testing-library/react';
-import React from 'react';
-
-import { createTestNode } from '../../utils/createTestNode';
-import { Element } from '../Element';
-
-let parentNode;
-let existingLinkedNode;
-let newLinkedNode = createTestNode('newLinkedNode');
-
-let toNodeTree = jest.fn().mockImplementation(() => ({
- rootNodeId: newLinkedNode.id,
-}));
-
-let addLinkedNodeFromTree = jest.fn();
-let parseReactElement = jest.fn().mockImplementation(() => ({
- toNodeTree,
-}));
-
-jest.mock('../../editor/useInternalEditor', () => ({
- useInternalEditor: () => ({
- actions: {
- history: {
- ignore: jest.fn().mockImplementation(() => ({
- addLinkedNodeFromTree,
- })),
- },
- },
- query: {
- parseReactElement,
- node: jest.fn().mockImplementation((id) => ({
- get() {
- if (id === 'parent-node') return parentNode;
- else return existingLinkedNode;
- },
- })),
- },
- }),
-}));
-
-jest.mock('../useInternalNode', () => ({
- useInternalNode: () => ({
- node: parentNode,
- inNodeContext: true,
- }),
-}));
-
-const NodeElementTest = jest.fn().mockImplementation(() => null);
-
-jest.mock('../NodeElement', () => ({
- NodeElement: jest.fn().mockImplementation((props) => NodeElementTest(props)),
-}));
-
-describe('', () => {
- beforeEach(() => {
- parentNode = createTestNode('test');
- });
-
- describe('when no id is passed', () => {
- it('should throw error', () => {
- expect(() => render()).toThrow();
- });
- });
-
- describe('when there is no existing node', () => {
- let elementProps, children;
-
- beforeEach(() => {
- elementProps = {
- color: '#fff',
- };
-
- children = Child
;
- render(
-
- {children}
-
- );
- });
-
- it('should call query.parseReactElement()', () => {
- const arg0 = parseReactElement.mock.calls[0][0];
- const arg0WithoutOwner = { ...arg0, _owner: null };
- expect(arg0WithoutOwner).toEqual(
- {children}
- );
- });
- it('should call actions.addLinkedNodeFromTree()', () => {
- expect(addLinkedNodeFromTree).toHaveBeenCalled();
- });
- it('should render a new linked Node', () => {
- expect(NodeElementTest).toHaveBeenCalledWith({
- id: newLinkedNode.id,
- });
- });
- });
-
- describe('when there is an existing node', () => {
- beforeEach(() => {
- existingLinkedNode = createTestNode('existing-linked-node', {
- type: 'div',
- props: {
- background: '#000',
- color: '#fff',
- },
- });
-
- parentNode = createTestNode('parent-node', {
- linkedNodes: {
- test: existingLinkedNode.id,
- },
- });
-
- render();
- });
- it('should render existing Node', () => {
- expect(NodeElementTest).toHaveBeenCalledWith({
- id: existingLinkedNode.id,
- });
- });
- });
-});