Search code examples
reactjsbackbone.jstinymcebackbone-views

Trying to render a React component from a Backbone View produces an error with no information


I have this really simple React app that is just for editing a character description using TinyMCE.

It works great as a standalone app, but I want to use it in an older WebApp game that uses Backbone.

Whenever I start the Backbone app game, and goto the Backbone view that is supposed to render the new React component, I just get a simple error that says, Error: Invariant Violation: _

There is no other information in the console or anywhere.

Is there something I could be doing wrong?

So here is my React app that uses TinyMCE:

import React from 'react';
import { Editor } from '@tinymce/tinymce-react';

class CharacterTextApp extends React.Component {
  handleEditorChange = (content, editor) => {
    console.log('Content was updated:', content);
  }

  render() {
    return (
      <Editor
        initialValue="<p>Your Character</p>"
        init={{
          height: 300,
          menubar: false,
          plugins: [
            'lists link image preview',
            'media paste help'
          ],
          toolbar:
            'undo redo | bold italic | \
            alignleft aligncenter alignright | \
            indent | help | image |'
        }}
        onEditorChange={this.handleEditorChange}
      />
    );
  }
}

export default CharacterTextApp;

And here is how I'm trying to call the react component in my Backbone view web game:

import Backbone from 'backbone';
import _ from 'underscore';
import template from 'text!./CharacterDescription.html';
import CharacterTextApp from 'new/components/CharacterTextApp';

export default Backbone.View.extend({
    className: 'characterData',
    template: _.template(template, null, { variable: 'ctx' }),

    initialize: function (args) {
        this.header = 'Your Character';
    },

    render: function () {
        this.$el.html(this.template({
            data: this.model.toJSON(),
            header: this.header
        }));
        
        this.renderCharacterTextApp();

        return this;
    },
    
    renderCharacterTextApp() {
    this.renderComponent(CharacterTextApp, {
        characterId: this.model.get('characterId'),
        onUpdate: (newId) => this.model.save('characterId', newId, {wait: true}),
    }, '#characterInformation');
    },
});

Solution

  • In my case, here is how I rendered a React component from a Backbone view.

    Say I have a React component called, myReactComponent and I want to pass in an Id and some data. #myDiv is the DOM element where I want the React component to be placed.

    In the Backbone view:

    this.renderComponent(myReactComponent, { someId: this.model.myId, someData: this.model.myData }, '#myDiv');
    

    In the React component, make sure you consume the props being passed:

    render() {
        const { someId, someData} = this.props;
    

    And that's it! Once I set it up like that, it worked fine!