Vue: rendering props cannot be utilized with TSX

After switching my setup from JSX in a Vue component to TS with vue-class-component, I found that only the code snippet below works for me (as shown in the example on repo):

import Vue from 'vue'
import { Component } from 'vue-property-decorator'

@Component
export default class TSXTest extends Vue {
  render(h) {
    return <h1>It works</h1>
  }
}

The key here is using h as shown in the example, which seems necessary. Although it should be automatically injected according to this.

In a scenario where I have a component accepting render props like below:

// This is a JS component, so it works even without manually adding `h`
render() {
    return (
      <td>
        {this.$props.render
          ? this.$props.render(this)
          : this.defaultRender(this)}
      </td>
    )
  }

The default rendering process works fine, but when attempting to pass a function with JSX, it fails to work in TSX, although it works perfectly for common Vue.js based components.

I used to write JSX inside the created hook like this:

created() {
    this.columns = [
      {
        field: 'fieldWithCustomRenderFn',
        label: 'Some name',
        renderCell: ({ row }) => (
          <div onClick={() => this.someHandler(row)}>
            {row.someData}
          </div>
        )
      }
    ]
}

Notably, there's no need to pass h in the above example, and it worked in JS but not in TSX. I'm unsure why...

When transpiled, the code looks like this:

renderCell: function renderCell(_a) {
        var row = _a.row
        return h('a', {
          on: {
            'click': function click(e) {
              _this.someHandler(row)
            }
          }
        }, [row.someData])
      }

Although the JSX is transformed, h appears to be undefined here. The difference I noticed between the working JS code and TSX code is the presence of this line:

var h = this.$createElement;

inside the created() function, which is absent in the transpiled code of my TSX component. What could be the issue here?

Below are snippets from my .babelrc file (using Babel 6):

"presets": [
    ["env", {
      "modules": "commonjs",
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 11"]
      }
    }],
    "stage-2"
  ],
  "plugins": [
    "syntax-dynamic-import",
    "transform-vue-jsx",
    "transform-runtime"
  ],

And webpack rules:

{
        test: /\.ts$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/],
          transpileOnly: true
        }
},
{
        test: /\.tsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true
            }
          }
        ]
},
{
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
},
{
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: file => (
          /node_modules/.test(file) && !/\.vue\.js/.test(file)
        )
}

Answer №1

It appears to be a well-known problem linked to babel-plugin-transform-vue-jsx. I managed to resolve it by manually inserting the following string within my JSX function:

const h = this.$createElement;

This solution allows the code to compile and function correctly, though it is merely a temporary workaround.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing the command `subprocess.run("npx prettier --write test.ts", shell=True)` fails to work, however, the same command runs successfully when entered directly into the terminal

Here is the structure of my files: test.py test.ts I am currently trying to format the TypeScript file using a Python script, specifically running it in Command Prompt on Windows. When I execute my python script with subprocess.run("npx prettier --w ...

Implementing a separate detail view in Vuejs

I am currently working on a page with multiple cases. When I click on a case, the details for that case appear on the same page. Here is a screenshot of how it looks: https://i.sstatic.net/Y9S4J.png As you can see in the screenshot, there are two cases li ...

Vue: The function "priceFilter" is not defined in this context

function sanitizeInput(event) { event.target.value = event.target.value.replace(/[^\d.]/g, ""); event.target.value = event.target.value.replace(/^\./g, ""); event.target.value = event.target.value.replace(/\.{2,}/g, "."); event.targe ...

Performing a search through a string array and updating a specific portion of each string

I am faced with an array containing a long list of Strings, and my goal is to filter out all the strings that begin with 'INSERT ALL' and replace the number inside the parentheses with the string ' NULL' Here is the original array: le ...

There are critical vulnerabilities in preact-cli, and trying to run npm audit fix leads to a never-ending loop between versions 3.0.5 and 2.2.1

Currently in the process of setting up a preact project using preact-cli: npx --version # 7.4.0 npx preact-cli create typescript frontend Upon completion, the following information is provided: ... added 1947 packages, and audited 1948 packages in 31s 12 ...

The error message related to TupleUnion in TypeScript is indicating that the depth of type instantiation may be too deep and could

Recently, I've been delving into a TypeScript utility type known as TupleUnion. This useful type came to my attention through a fascinating Twitter post, and I've observed it being utilized in various Stack Overflow solutions. Here's how the ...

Angular 2 does not recognize the existence of .then in type void

I have a query regarding Angular2 and I'm struggling with the void function in my code. Can someone help me out? I am new to Angular2 and unsure of what needs to be added in the void function. Check out this image for reference export class PasswordR ...

I've come across certain challenges when setting values for Vue data objects

I'm having trouble with a Vue assignment. Here is my code: new Vue({ el: "#alarmEchartBar", data: { regusterUrl: Ohttp + "historicalAlarmRecord/chart", regDistrictUrl: Ohttp + "district", regStreetUrl: Ohttp + "street/", regCameraUrl: ...

A guide on how to implement promise return in redux actions for react native applications

I'm using redux to handle location data and I need to retrieve it when necessary. Once the location is saved to the state in redux, I want to return a promise because I require that data for my screen. Here are my actions, reducers, store setup, and ...

Make sure to implement validations prior to sending back the observable in Angular

Each time the button is clicked and if the modelform is invalid, a notification message should be returned instead of proceeding to create a user (createUser). The process should only proceed with this.accountService.create if there are no form validation ...

Exploring Angular Unit Testing: A Beginner's Guide to Running a Simple Test

I'm diving into the world of angular unit testing and looking to set up my first successful test. Here's what I've come up with: import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { AppComponent } fro ...

The object's null status remains uncertain even after being checked for null

Currently, I am working with Typescript 2.8 This is the code snippet that I have: class Wizard extends React.Componenet { private divElement: null | HTMLDivElement = null; componentDidUpdate(_: IWizardProps, prevState: IWizardState) { i ...

Utilizing TypeScript with Sequelize for the Repository Design Pattern

I am in the process of converting my Express API Template to TypeScript, and I am encountering difficulties with the repositories. In JavaScript, the approach would be like this: export default class BaseRepository { async all() { return th ...

The for loop displays only the most recent data fetched from Firebase

When using a for loop to retrieve a user's progress, I encounter an issue. In Typescript: this.userProgress = af.object('/UserProgress/' + this.currentUser + '/', { preserveSnapshot: true }); this.userProgress.subscribe(snaps ...

Explore Syncfusion Vue component for dynamic element manipulation and customization

While working with syncfusion Vue controls, I've noticed that the documentation provides examples that access controls using $refs in some cases, while in others they use raw JavaScript like getelementbyid. At times, trying to use $refs results in pro ...

Looking for a TypeScript annotation that allows accessing an object property using a variable

When working with plain JavaScript, we have the ability to access an object's property value using a variable. For example, this is permitted: let obj = { a: 100, b: 'Need help with TypeScript', c: new Date() }; let prop = 'b'; c ...

Transitioning from MVC to Angular 2 and TypeScript: A Step-by-Step Guide

Seeking guidance as I venture into the world of Angular. My goal is to pass a string variable 'element' to my UI and utilize it. However, I am unsure about how to go about passing it inside main.js and beyond. How can I transfer a variable to a t ...

Typescript's Integrated Compatibility of Types

One important concept I need to convey is that if one of these fields exists, then the other must also exist. When these two fields are peers within the same scope, it can be challenging to clearly communicate this connection. Consider the example of defi ...

Guide on implementing a cordova plugin in a TypeScript cordova application

In my Cordova project, which utilizes Angular and Typescript, I am facing issues with implementing the juspay-ec-sdk-plugin for Cordova. I have explored possible solutions on StackOverflow related to integrating Cordova plugin in an Angular 4 Typescript ...

Dynamically binding image URLs in VUEJS

Below is the JSON data containing button names and their corresponding image URLs: buttonDetails= [ { "name": "button1", "images": [{ "url": "https://localhost:8080/asset/d304904a-1bbd-11e6-90b9-55ea1f18bb ...