wix-incubator / react-templates

Light weight templates for react
https://wix.github.io/react-templates
MIT License
2.82k stars 207 forks source link

react-native error React.createElement is not a function #168

Open PierBover opened 8 years ago

PierBover commented 8 years ago

I'm trying to use react-templates with react-native.

I'm compiling the templates using rt template.rt --modules commonjs --native --react-import-path react-native.

From this template:

<View>
    <Text>{this.props.text}</Text>
</View>

I get this .js file:

'use strict';
var React = require('react-native');
var _ = require('lodash');
module.exports = function () {
    return React.createElement(React.View, {}, React.createElement(React.Text, {}, this.props.text));
};

But when trying to use the component I get the error React.createElement is not a function.

I import the template with import template from './template.rt.js' and then I've tried different ways of declaring the render function but I always get the same error.

MyComponent.prototype.render = template

MyComponent.prototype.render = template()

render () {
    return template.apply(this);
}

render () {
    return template().bind(this);
}

Could this be a bug or am I missing something?

nippur72 commented 8 years ago

I'm not acquainted with react-native so I'm just guessing:

By looking at the hello world example from react-native website:

import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';

I see that it's different from what react-templates is currently putting out.

I suspect there was a breaking change in react-native and react-templates is lagging behind.

nippur72 commented 8 years ago

Indeed:

From https://github.com/facebook/react-native/releases/tag/v0.26.0 released May 19, 2016

React API must be now required from react package (previously a warning on 0.25)

nippur72 commented 8 years ago

If it's so, revert back to importing react and manually require components from react-native.

Let me know if that works.

PierBover commented 8 years ago

I've manually changed:

var React = require('react-native');

To this:

import React from 'react';

But now I get the error:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `Button`.
nippur72 commented 8 years ago

I guess Button and other ui elements need to be imported from react-native as in:

import { Button } from 'react-native';

but ofc you can do that from within .rt file using <rt-import>

PierBover commented 8 years ago

No, Button is importing the template.

If I remove the template and use regular JSX it works fine.

nippur72 commented 8 years ago

ops, i meant "view" instead of button. Its undefined because it's not loaded from react-native.

Also, it should not be "React.View" but just "View", so this definitely needs to be fixed.

PierBover commented 8 years ago

You were 100% right!

I manually changed the code to this and now it works as expected:

'use strict';
import React from 'react';
import {
  Text,
  View
} from 'react-native';

var _ = require('lodash');
module.exports = function () {
    return React.createElement(View, {}, React.createElement(Text, {}, 'Hola'));
};
nippur72 commented 8 years ago

I have a PR for this. If it's merged there will be no need to import each single components from react-native, as the new emitter will pick them when needed, e.g:

'use strict';
var ReactNative = require('react-native');
var React = require('react');
var _ = require('lodash');
module.exports = function () {
    return React.createElement(ReactNative.View, {});
};
Clay-Ferguson commented 6 years ago

I was getting error: "React.createElement is not a function" and for my situation the fix was to change this:

import * as React from "react";
import * as ReactDOM from "react-dom";

TO THIS:

import React from "react";
import ReactDOM from "react-dom";

This was in a TypeScript file so i'm not sure it applies to non-TypeScript or not.

jinhale commented 4 years ago

I was getting error: "React.createElement is not a function" and for my situation the fix was to change this:

import * as React from "react";
import * as ReactDOM from "react-dom";

TO THIS:

import React from "react";
import ReactDOM from "react-dom";

This was in a TypeScript file so i'm not sure it applies to non-TypeScript or not.

Thanks, I fixed this by changing import React from 'react-native'; to import React from 'react';.