Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Error calling React from Vue ("h is not a function") #31

Closed
tmepple opened this issue Mar 5, 2018 · 8 comments
Closed

Error calling React from Vue ("h is not a function") #31

tmepple opened this issue Mar 5, 2018 · 8 comments

Comments

@tmepple
Copy link

tmepple commented Mar 5, 2018

I'm having issues calling a React component from a freshly generated Vue project and must be doing something wrong.

So, starting with vue --version at 2.9.3 (the latest released version) and accepting the defaults in the vue-cli script.

vue init webpack myapp
cd myapp
yarn add vuera react react-dom

Now, I modified the generated /src/main.js entrypoint to import and use the VuePlugin from vuera:

import Vue from 'vue'
import App from './App'
import { VuePlugin } from 'vuera'

Vue.config.productionTip = false

Vue.use(VuePlugin)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

Modified the generated App.vue to import and attempt to use the React component:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <HelloWorld/>
    <react-component message="Hello"></react-component>
  </div>
</template>

<script>
/* eslint-disable */
import HelloWorld from "./components/HelloWorld";
import ReactComponent from "./components/ReactComponent";

export default {
  name: "App",
  components: {
    HelloWorld,
    "react-component": ReactComponent
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Finally added the simple React component /components/ReactComponent.js:

import React from 'react'

export default class ReactComponent extends React.Component {
  render() {
    return (
      <div>
        <p>This was rendered with React!</p>
        <p>{this.props.message}</p>
      </div>
    )
  }
}

Webpack compiles everything fine, but when requesting http://localhost:8080 my React component is not rendered under the "Hello World" Vue component. Instead I get 4 errors in the console starting with "Uncaught TypeError: h is not a function".

screen shot 2018-03-05 at 9 31 07 am

I also tried using the ReactWrapper but had the same result.

I'm at the latest vuera 0.2.1, vue 2.5.13, react & react-dom 16.2.0, webpack 3.11.0.

This library looks to be awesome once it's working, thanks for any help!

@tmepple
Copy link
Author

tmepple commented Mar 6, 2018

Ok, I figured it out and now it works.

In .babelrc in a default Vue project the first plugin specified is transform-vue-jsx which was converting my jsx into an h function call suitable for Vue.

The fix is to replace that with transform-react-jsx (this and the vue plugin are mutually exclusive) and yarn add --dev babel-plugin-transform-react-jsx. Now it works perfectly. Thanks again for the great library.

@tmepple tmepple closed this as completed Mar 6, 2018
chunghe added a commit to chunghe/react-in-vue that referenced this issue Sep 13, 2018
replace `transform-react-jsx` with `babel-plugin-transform-react-jsx` to
avoid `h is not a function`
@Enigma10
Copy link

Enigma10 commented Feb 4, 2019

@tmepple @akxcv Hi Guys, Can help me with this? I am not able to fix this issue with CLI 3 which is having babel.config.js instead of .babelrc.

@elevatebart
Copy link

Hey @Enigma10 have you tryed using overrides ? they worked like a charm for me.
Something like this

module.exports = api => ({
    presets: ["@babel/env"],
    overrides: [
        {
            test: ["./src"],
            presets: [["@vue/app"]]
        }
    ]
});

@mpan-wework
Copy link

https://github.com/mpan-wework/vuera-test/blob/afa01e5f25adc0c64a46873e185a8e64464ce42e/babel.config.js#L1-L11

@suenot
Copy link

suenot commented Apr 15, 2019

Spend a lot of time to solve this problem. "@vue/app" in current version included vue jsx support, that conflicted with react jsx.
My babel.config.js:

module.exports = {
  presets: [
    ["@babel/preset-env"],
    ["@babel/preset-react"],
  ],
  plugins: [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    ["@babel/plugin-syntax-jsx"],
    ["@babel/plugin-transform-react-jsx"],
    ["@babel/plugin-syntax-dynamic-import"],
    ["@babel/plugin-transform-runtime"],
  ],
}

@suenot
Copy link

suenot commented Apr 27, 2019

@akxcv, is it possible to use vue jsx and react jsx together?

@akxcv
Copy link
Owner

akxcv commented Apr 27, 2019

In theory, yes, if during build time you can use Babel with different transforms for Vue and React files.
For example, you could set up Webpack to transform .vue files with @vue/app and .jsx files with React's plugin pipeline.

@amc1999
Copy link

amc1999 commented Dec 6, 2019

@mpan-wework solution works great for me, thank you. There is only minor tweak - I prefer not to comment out entire preset // '@vue/app' but rather disable only Vue jsx plug-in:

// babel.config.js
module.exports = {
  presets: [
    ['@vue/cli-plugin-babel/preset', {'jsx': false}],
    ['@babel/preset-react'],
    ['@babel/preset-env']
  ],
  plugins: [
    ['transform-react-jsx'],
    ['@babel/plugin-syntax-dynamic-import']
  ]
}

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

No branches or pull requests

7 participants