craft.js icon indicating copy to clipboard operation
craft.js copied to clipboard

Frame Element: Invariant Violation

Open verystack opened this issue 5 years ago • 14 comments

Describe the bug Invariant violation when running Basic example inside React App. Error occurs on <Frame> element and below.

Uncaught Error: Invariant failed: A <Element /> that is used inside a User Component must specify an id prop, eg: <Element id="text_element">...</Element>.

To Reproduce

  1. Install Basic project dependencies, and move folders to correct locations
  2. Import the index.js function export into an existing React Component.
  3. Error on load

Expected behavior The Basic Example's main export is a function component, which should mean it is importable within an existing React App.

Your environment

Software Version(s)
craft.js 0.1.0-beta.13
React 16.12.0
TypeScript none
Browser Opera 72.0.3815.320 (Chrome 86)
npm/Yarn 6.14.5
Operating System Windows 10 x64

verystack avatar Nov 16 '20 07:11 verystack

I'm having the same problem here, tried to reproduce the "simple" example.

<Frame>
  <Element is="div" style={{ background: '#333' }} canvas>
    <Text text="Sample" />
  </Element>
</Frame>

My text component:

const TextComponent = ({ text }: { text: string }) => {
  const {
    connectors: { drag },
  } = useNode();

  return (
    <div ref={drag}>
      <h2>{text}</h2>
    </div>
  );
};

export default TextComponent;

And finally, my Toolbox:

export default function Toolbox() {
  const { connectors } = useEditor();

  return (
    <Box pad="medium" background="white">
      <Heading>Toolbox</Heading>

      <Button ref={(ref) => connectors.create(ref, <Text text="demo" />)}>
        Text
      </Button>
    </Box>
  );
}

Screen Shot 2021-02-01 at 11 25 41 AM

thiagoterleski avatar Feb 01 '21 18:02 thiagoterleski

Hi @thiagoterleski

I converted your example into a CodeSandbox without the styling and it works without the error.

Are you able to reproduce it in the Codesandbox, or are you able to fix your error by looking at the example?


Edit: Maybe there was a mismatch between using <Text /> but the UserComponent is called TextComponent? If that is the case, you could either rename <TextComponent /> to <Text /> or rename it in the resolver: <Editor resolver={{ Text: TextComponent />

ankri avatar Feb 01 '21 18:02 ankri

@ankri Thanks for trying to reproduce the issue, I copied the exact same code from the sandbox, and the problem still happens 😱 Same React version (17), I reinstalled all my node-modules and restarted the app.

The only way to not break the app is by removing the Element from the frame parent component. (But of course, this won't work) Just mentioned it because it is something related to the Element component.

I can't think of anything else that could trigger this error. You can see my code is exactly the same as your example:

import React from 'react';
import Container from './blocks/Container';
// import Text from './blocks/Text';
import { Editor, Element, Frame, useEditor, useNode } from '@craftjs/core';
// import Toolbox from './Toolbox';

const Text = ({ text }: { text: string }) => {
  const {
    connectors: { drag, connect },
  } = useNode();

  return (
    <div ref={(ref) => connect(drag(ref))}>
      <h2>{text}</h2>
    </div>
  );
};

const Toolbox = () => {
  const { connectors } = useEditor();

  return (
    <div style={{ padding: '2rem' }}>
      <h1>Toolbox</h1>

      <button ref={(ref) => connectors.create(ref, <Text text="demo" />)}>
        Text
      </button>
    </div>
  );
};

export default function BuilderContainer() {
  return (
    <Editor resolver={{ Text }}>
      <Frame>
        <Element is="div" style={{ background: '#333' }} canvas>
          <Text text="Sample" />
        </Element>
      </Frame>
      <Toolbox />
    </Editor>
  );
}

thiagoterleski avatar Feb 01 '21 20:02 thiagoterleski

@thiagoterleski see this sandbox that demonstrates where the issue comes from, its basically a safe check for nested Canvas components that don't have a valid id. Please double check that this doesn't happen in your case!

matdru avatar Feb 01 '21 21:02 matdru

@matdru Thanks for the example, I was able to fix the problem by removing the hot reload wrapper from my App.js. I was testing the code in different levels in the app and noticed it worked when I tested directly in the index file. Not sure why it would trigger this specific error but it worked after removing it. 🤷‍♂️

Screen Shot 2021-02-01 at 2 48 12 PM

thiagoterleski avatar Feb 01 '21 21:02 thiagoterleski

Same issue here. Can't get it to work even when using a simple example such as the one @thiagoterleski provided. And I have disabled hot reload too. Using React 16.8.0 and @craftjs/core 0.1.0-beta.16. Bummers because this package is exactly what i need :(

Edit: I have also tested it with 0.2.0-alpha.16 Does this package actually work?

palttamas avatar Mar 09 '21 16:03 palttamas

@PalTamasWBA please checkout sandbox above to see what is causing the issue, alternatively if you can provide a small sandbox with your setup we can try to debug. Version 0.2.0 has some breaking changes compared to 0.1.0, but both should be operational and useable.

matdru avatar Mar 09 '21 16:03 matdru

@matdru sorry for going off topic but these breaking changes from v0.1.x to 0.2.x are documented somewhere? i see that 0.1.0-beta.11 is considered the stable version, which one is suggested to be used in production? is v0.1 going to be deprecated soon? Thanks

nicosh avatar Mar 10 '21 08:03 nicosh

@matdru I have managed to fix it. It turns out indeed this has something to do with hot reloading. It wasn't enough to remove the hot reload wrapper, i also needed to remove the hot flag from the webpack dev server.

Did you come across something like this whilst developing the package?

palttamas avatar Mar 10 '21 10:03 palttamas

@PalTamasWBA i don't recall having any issues like that, but to be honest i'm most often using a basic CRA react starter for any development, so i hadn't tested it across other setups. If you are using any specific starter that was giving you these issues, feel free to link it i can try and investigate it further.

matdru avatar Mar 10 '21 15:03 matdru

@nicosh We realised there are some unfortunate design choices in internal API's and craft state structures that don't scale too well in the long run, so that's when 0.2.0 was born. I think that's where active development has shifted to these days ( correct me if im wrong @prevwong 😸 ). That being said since a lot of people are currently running their projects on 0.1.0 so we still accept PR's for bug fixes and improvements and it's going to be a while before we deprecate it fully. When we do there will be a migration guide posted and we will try to keep it as simple and straightforward as possible 🤞

matdru avatar Mar 10 '21 16:03 matdru

@thiagoterleski @matdru it's sorted. I had to fix a warning that said "React dom patch not detected" I followed this comment https://github.com/gaearon/react-hot-loader/issues/1227#issuecomment-482514844

Edit: I'm using "@symfony/webpack-encore": "^0.30.2", which is similar to laravel mix if anybody is familiar with those. It's a wrapper around webpack, so I realize my setup is unusual. Thanks for your help! :smile:

palttamas avatar Mar 11 '21 14:03 palttamas

For me, changing

<Element id="canvas" className="canvas" canvas></Element>

to

<Element id="canvas" is="div" className="canvas" canvas></Element>

.. solved it.

fraank avatar Jun 27 '21 12:06 fraank

For me this issue arised when trying to have a Container-based component that accepted any children. (No is attribute on the Element tag)

What worked for me was to create a "constraint" anyway, and use that.

For example:

export const Anything = ({children}) => <div>{children}</div>

Anything.craft = {rules: {canMoveIn: () => true}}; 

Usage:

<Element canvas id="sth" is={Anything}>

denis-ismailaj avatar Aug 09 '21 21:08 denis-ismailaj