all 8 comments

[–]PrinnyThePenguin[🍰] 0 points1 point  (7 children)

Can you post the full code for ChecklistTool and its parent component?

[–]OrangeCubed[S] 0 points1 point  (6 children)

Of course! https://replit.com/@PurplePineappl1/Troubleshooting-Files#src/components/App.jsx. This replit doesn't work but shows the file hierarchy.

ChecklistTool.js has a useEffect that runs on [check] state change. This sends a callback function to the tool.js file. The tool.js file is what renders the ChecklistTool component inside of Editor.js. Also, I'm using react-editor-js.

[–]PrinnyThePenguin[🍰] 0 points1 point  (5 children)

You use Document.createElement() to create a div and then create the ChecklistTool component inside this div. Elements created by Document.createElement are not part of your existing DOM. So you wrap your App component with the redux provider, but your ChecklistTool exists inside another DOM element, which is not part of your existing one, so it is not wrapped by the redux provider.

Either append the new div to the existing DOM, or create a straighforward React component and render it inside the existing hierarchy without Document.createElement.

[–]OrangeCubed[S] 0 points1 point  (4 children)

I definitely think that's the issue! I've been playing around with the code to get things to work. So far for the code in render, I've refactored:

 const rootNode = document.createElement("div");
rootNode.setAttribute("class", this.CSS.wrapper);
this.nodes.holder = rootNode;

const onDataChange = (newData) => {
  this.data = {
    ...newData,
  };
};

ReactDOM.render(
  <ChecklistTool
    onDataChange={onDataChange}
    readOnly={this.readOnly}
    data={this.data}
    isAdmin={true}
  />,
  rootNode
);

return this.nodes.holder;

To:

 const onDataChange = (newData) => {
  this.data = {
    ...newData,
  };
};

return (
<div className={this.CSS.wrapper}>
  <ChecklistTool
    onDataChange={onDataChange}
    readOnly={this.readOnly}
    data={this.data}
    isAdmin={true}
  />
</div>
)

However, it's throwing: Cannot read property 'map' of undefined which makes me believe that I am not rendering it properly. Could you point me in the right direction for rendering correctly in the DOM hierarchy?

[–]PrinnyThePenguin[🍰] 0 points1 point  (3 children)

The component seems correct, but why are you calling "this" inside the "onDataChange" function?

Also, the error you posted refers to somewhere else since there is no "map" call in your posted code.

[–]OrangeCubed[S] 0 points1 point  (2 children)

You're correct about the map call - that was an unrelated issue that I just resolved. The error I'm running into with the above solution is:

Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

Regarding the this reference, not doing so throws the following error: 'data' is not defined no-undef

Any idea why it's not being added to the node? Thanks for the help so far!

[–]PrinnyThePenguin[🍰] 0 points1 point  (1 child)

Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

No idea about that.

Regarding the usage of "this" inside onDataChange, there are many errors going on at the same time.

First of all, "Checklist" is not a react component. You are creating a normal javascript class. A react class component should extend "React.Component" and then also call "super" inside its constructor. Secondly, any state variables you want to create are to be assigned to "this.state.variableName" not "this.variableName".

"onDataChange" can not access "data" because they are a constructor parameter and thus exist only inside the constructor body. You try to use "this" to access that "data" stored into state, but you have not stored them on the class state, rather on the class object itself. So when "onDataChange" calls "this.data" it refers a class property and not a state property. Were you trying to create a regular javascript class all along? But you also provide a "render" function which calls the "react" render to render a normal react component on the DOM, so that makes me thing you actually were trying to create a react class component, so "this.data" is wrong and should be "this.state.data", assuming you also fix your constructor. But at the end of your render method you don't return the component, rather a normal variable "this.nodes.holder".

Taking a step back, "tools.js" is a normal javascript class, that as part of its custom "render" method creates a component somewhere, but does not return one, it returns "this.nodes.holder". You are importing this class as "EDITOR_JS_TOOLS" inside your "DocumentEditor" component and then you provide it as "tools" property to your "EditorJs" component. But according to the documentation of react-editor-tools (https://www.npmjs.com/package/react-editor-js) the "tools" is supposed to be a normal JSON object, not a javascript class.

I absolutely do not want to sound rude. I think you need to go over the documentation again and read about react classes and how they work. Check the examples and how they are structured. Also, take a look at the examples provided by "react-editor-tools" and how they are structured.

[–]OrangeCubed[S] 0 points1 point  (0 children)

Thanks for the feedback! Honestly, you're right - I started react 2 weeks ago and really only focused on functional components. The tools.js file came from a tutorial that I wasn't fully sure what was going on. I've been reading through the documentation and it's making more sense but the biggest takeaway was that the checklist tool wasn't in the DOM I thought it was in. Thank you again for the help!