atom / etch

Builds components using a simple and explicit API around virtual-dom
MIT License
555 stars 57 forks source link

“React is not defined” while using etch in atom? #54

Closed daiict218 closed 7 years ago

daiict218 commented 7 years ago

Although React is not a dependency of etch, it says "React is not defined".

my plugin code is as follows :

> 'use babel';

import NewPluginView from './new-plugin-view';
import { CompositeDisposable } from 'atom';

export default {

  newPluginView: null,
  modalPanel: null,
  subscriptions: null,

// document.body.appendChild(component.element)

  activate(state) {
    this.newPluginView = new NewPluginView(state.newPluginViewState);
    this.modalPanel = atom.workspace.addModalPanel({
      item: this.newPluginView.getElement(),
      visible: false
    });

    // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
    this.subscriptions = new CompositeDisposable();

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'new-plugin:toggle': () => this.toggle()
    }));
  },

  deactivate() {
    this.modalPanel.destroy();
    this.subscriptions.dispose();
    this.newPluginView.destroy();
  },

  serialize() {
    return {
      newPluginViewState: this.newPluginView.serialize()
    };
  },

  toggle() {
    console.log('NewPlugin was toggled!');
    return (
      this.modalPanel.isVisible() ?
      this.modalPanel.hide() :
      this.modalPanel.show()
    );
  }

};

and My view code is as follows :

'use babel';

import etch from 'etch';

export default class NewPluginView {

  constructor(serializedState) {
    // Create root element
    // this.element = document.createElement('div');
    // this.element.classList.add('new-plugin');
    //
    // // Create message element
    // const message = document.createElement('div');
    // message.textContent = 'The NewPlugin package is Alive! It\'s ALIVE!';
    // message.classList.add('message');
    // this.element.appendChild(message);
    // console.log('this package');
    etch.initialize(this);
  }

  update(props, children) {
    return etch.update(this);
  }
  // Returns an object that can be retrieved when package is activated
  serialize() {}

  // Tear down any state and detach
  destroy() {
    //this.element.remove();
  }

  getElement() {
    return this.element;
  }

  render() {
    return (
     <div></div>
    );
  }
}

Can someone help me?

lloiser commented 7 years ago

You have to add /** @jsx etch.dom */ after "use babel" in your "view" file. This tells babel how to "translate" the <div></div>. By default babel translate it into React.createElement('div') but with the above comment it uses etch.dom('div') instead.

nathansobo commented 7 years ago

You can also use plain JS by calling helper methods defined on etch.dom, as follows:

const etch = require('etch')
const $ = etch.dom

$.div(null, $.span(null, 'hello'), $.span({style: {fontWeight: 'bold'}}, 'world'))

Not as pretty but simpler in a lot of ways.

Anyway, closing this out. Thanks @lloiser for answering this.