Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frame Element: Invariant Violation #141

Open
verystack opened this issue Nov 16, 2020 · 14 comments
Open

Frame Element: Invariant Violation #141

verystack opened this issue Nov 16, 2020 · 14 comments

Comments

@verystack
Copy link

verystack commented Nov 16, 2020

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
@thiagoterleski
Copy link

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

@ankri
Copy link
Collaborator

ankri commented Feb 1, 2021

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 />

@thiagoterleski
Copy link

@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>
  );
}

@matdru
Copy link
Collaborator

matdru commented Feb 1, 2021

@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!

@thiagoterleski
Copy link

@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

@palttamas
Copy link

palttamas commented Mar 9, 2021

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?

@matdru
Copy link
Collaborator

matdru commented Mar 9, 2021

@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.

@nicosh
Copy link

nicosh commented Mar 10, 2021

@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

@palttamas
Copy link

@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?

@matdru
Copy link
Collaborator

matdru commented Mar 10, 2021

@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
Copy link
Collaborator

matdru commented Mar 10, 2021

@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 🤞

@palttamas
Copy link

palttamas commented Mar 11, 2021

@thiagoterleski @matdru it's sorted. I had to fix a warning that said "React dom patch not detected"
I followed this comment gaearon/react-hot-loader#1227 (comment)

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! 😄

@fraank
Copy link

fraank commented Jun 27, 2021

For me, changing

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

to

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

.. solved it.

@denis-ismailaj
Copy link

denis-ismailaj commented Aug 9, 2021

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}>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants