Babel does not transpile a JSX instance of an arrow function - reactjs

my Javascript & React level is beginner.
I'm having fun with https://babeljs.io/repl to see how my JSX is transpiled into an older version of Javascript, and there is something I don't quite understand.
I'm trying to use an arrow function and an instance of this function :
const App = () => {
return <div></div>;
}
<App></App>
Which throws me an error :
repl: Unexpected token (5:6)
3 | }
4 |
> 5 | <App></App>
| ^
Note that a normal function AND it's instance () is working fine. An arrow function ONLY is working fine too. The problem happens when i use an arrow function AND the JSX instanciation of it.
Thank you !!

The problem happens when i use an arrow function AND the JSX instanciation of it.
That's the problem here. In order to be parsed correctly, <App></App> should be unambiguously identified as JSX. This cannot be done because a semicolon after an arrow was omitted.
It should be:
const App = () => {
return <div></div>;
};
<App></App>
As another answer mentions, JSX syntax is usually used in situations like ReactDOM.render(...) where it can be unambiguously identified as an expression, so this problem won't occur in this case.

Please also note that having <App></App> on file-level scope - while being technically correct - will result in discarding a value that it produces - no component will be mounted. Usually, one would use ReactDOM's render method to render React components' tree:
const root = document.getElementById("root");
ReactDOM.render(<App />, root)

Related

Replace DOM with JSX in React 18

How to remove this error message from my console
I'm using ReactDOM.render to replace certain "unreachable" parts of my code with JSX components, it worked fine in previous versions but now I'm getting this annoying error message and I want to get rid of it.
Long story:
I'm using the FullCalendar lib for react18 and Nextjs.
I'm facing a limitation from the lib, in previous versions I was able to pass JSX to render in the header buttons, but in the current version 5.11.2 it's not possible anymore, it only let you set either text or a bootstrap/font-awesome icon.
So I instead used an old known trick to replace DOM with no more than the HTML element
ReactDOM.render(
<AnyIconIWantToUse />,
window.document.querySelector("#element-to-replace-id")
)
and that is what brings up the said error message
What I've tried
As the error suggest I've tried using createRoot instead but it gives me an error too (and afaik it's meant to be used only with the root component so I prefer not to use it).
This should help you out
createPortal(
<AnyIconIWantToUse />,
document.getElementById("element-to-replace-id")
)
I ended up achieving what I wanted with another approach.
Instead of replacing DOM content directly with JSX I instead render the desired JSX into the DOM and replace the DOM with DOM
// utils/replaceDOM.ts
import type React from 'react';
import { renderToString } from 'react-dom/server';
type ReplaceDOM = (
elementToReplace: Element,
replacement: React.ReactElement
) => void;
const replaceDOM: ReplaceDOM = (elementToReplace, replacement) => {
if (!replacement) return;
// Get html from component (only get first render)
const replacementHTML = renderToString(replacement);
// Parse html string into html
const parser = new DOMParser();
const parsedDocument = parser.parseFromString(replacementHTML, 'text/html');
const replacementElement = parsedDocument.body.children[0];
// Append replacement to DOM
window.document.body.prepend(replacementElement);
// Replace children with element
elementToReplace.replaceWith(replacementElement);
};
export default replaceDOM;
Then I can use it as desired
replaceDOM(elementToReplace, <ElementIWant className="w-6" />);

I want to write other languages code in react js

I am working on building a website.
I made all things, but now I'm stuck in adding code to the website.
I want to put some codes inside the JSX component but it is having some problems with adding { <<these types of symbols.
Is there any way I can write the C++ code or C code inside the react element?
import React from 'react'
const Template = () => {
return (
<div>
<h1></h1>
</div>
)
}
export default Template
The JSX won't appreciate the "{ <<", but if you want a quick in on this, you may try something like this -
const SomeCode = ()=><code>{`#include <stdio.h>;`}</code>
That might not be sufficient - you may need proper highlighting with specific programming language, formatting, etc. for what you might be building. But just for getting literals such as << working with JSX - you may take the above example as base.
In JSX, which is what react usees, brackets will be parsed.
Therefore, strings should be inside {`content`}, or you can define that code as a string, and place it inside jsx as below
const SomeComponent = ()=>{
const codeSnippet = `{ << whatever code blahblah`
return <div>
{codeSnippet}
</div>
}

What is the preferred syntax for a stateless react function? Why?

Method 1:
const BasicProfileInfo = (props: BasicProfileInfoProps) => {
return (
<MainContainer>
{....}
</MainContainer>
)
}
Method 2:
function BasicProfileInfo(props: BasicProfileInfoProps){
return (
<MainContainer>
{....}
</MainContainer>
)
}
Project Environment:
babel-eslint: 8.0.2
babel-plugin-transform-class-properties: 6.24.1
babel-preset-es2015: 6.24.1
babel-preset-react-native: 4.0.0
react: 16.0.0
react-native: 0.48.4
mobx: 3.3.1
mobx-react: 4.3.3
Arrow function can be shortened to implied return:
const BasicProfileInfo = (props: BasicProfileInfoProps) => (
<MainContainer>
{....}
</MainContainer>
);
But it has a bit more footprint in ES5 output than regular function declaration, because an arrow is transpiled to regular function any way:
var BasicProfileInfo = function BasicProfileInfo(props) { return ... }
This is the only difference between them as stateless components. Arrow functions don't have their own this and arguments, but this isn't the case.
One advantage of using the 'arrow function' notation is that arrow functions don't have their own this value, which is useful if you want to preserve this from an outer function definition.
But, if your component is stateless, this doesn't matter, so it doesn't matter which one you use.
React components will use the function name as the displayName in debug messages and the developers console. The default displayName is Component, which is much less useful. This alone I think is enough to always prefer explicitly named functions (Method 2).
EDIT: As noted below, either of OP's methods will result in the displayName being populated correctly. The only situation that it will not is when exporting truly anonymous functions like: export default () => {}. So the other answers here are more relevant.

How can I suppress "The tag <some-tag> is unrecognized in this browser" warning in React?

I'm using elements with custom tag names in React and getting a wall of these errors. There's a GitHub issue on the subject (https://github.com/hyperfuse/react-anime/issues/33) in which someone states:
This is a new warning message in React 16. Has nothing to do with anime/react-anime and this warning can safely be ignored.
It's nice that it can be safely ignored, but it's still not going to pass scrutiny when my code is filling the console with useless error messages.
How can I suppress these warnings?
I found a potential fix for this issue - if you are using a plugin (and potentially in other circumstances) you can use the is attribute.
Found here when working with X3d - simply writing <scene is="x3d" .../> works
Update:
see the answer from #triple with the correct solution:
https://stackoverflow.com/a/55537927/1483006
Orignal:
I'm not saying this a correct thing you should really do, but you could hook console.error and filter this message by putting this somewhere before react-anime is loaded:
const realError = console.error;
console.error = (...x) => {
// debugger;
if (x[0] === 'Warning: The tag <g> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.') {
return;
}
realError(...x);
};
It seemed to work on the sample that was posted in the GitHub issue you linked at least. :3
My solution was to create envelope component which renders <div> with desired classes:
import React, {Component, DetailedHTMLFactory, HTMLAttributes} from "react";
import classNames from "classnames";
export default class SimpleTagComponent extends Component<SimplePropTypes>{
baseClassName = 'simpleComponent'
render() {
return React.createElement(
'div',
{
...this.props,
className: classNames(this.baseClassName, this.props.className),
},
this.props.children
);
}
}
type SimplePropTypes = HTMLAttributes<HTMLDivElement>
export class MyTag extends SimpleTagComponent {
baseClassName = 'my'
}
I don't believe there's a built in way to suppress the error message.
The warning message is logged right here in react-dom. You could fork react-dom and simply remove the error message. For a change as small as this, perhaps using something like patch-package would be useful, so you don't have to maintain a fork.
React 16 gives warnings with x3dom components .
including is="x3d" in component suppresses these warnings.
I had the same error. My problem was the new file for js when I use sfc I first letter of the name (tagname) has to be capital letter. I am just new so, I didn't notice it. But I am writing this just in case
I wrapped my HTML in the <svg> tag.
https://github.com/facebook/react/issues/16135:
I think you're probably rendering them outside of <svg> tags.
This is what got rid of the Web Browser Warnings for me:
BAD:
const SocialMedia = (props) => {
<socialmedia>
return (
Good:
const SocialMedia = (props) => {
return (

Use of curly braces in React

I am trying to learn React.
I am having trouble with the use of curly braces.
Use of curly brace makes difference between JSX and JS
In the code below,
Curly Brace 1 says "now it is JS".
Why is there curly brace 2 ? It is already inside a curly brace zone ?
var React = require('react');
var ReactDOM = require('react-dom');
var MyCompClass = React.createClass({ // open curly brace 1
render: function () { // open curly brace 2
return <h1>Hello</h1>;
}
});
ReactDOM.render(
<MyCompClass />,
document.getElementById('app')
);
A second quick question :
ReactDOM.render(
<MyCompClass />,
document.getElementById('app')
);
why do .render() need HTML marks around MyComponentClass ?
Thank you for your help !
You are calling React.createClass method with object parameter. The first curly braces is the syntax of standard javascript object. In this object there is a property called as 'render'. This render attribute could be a function, so the second curly braces are the scope of javascript function syntax.
Also, the HTML marks in your render method is your React component and this is JSX syntax.
So, the following documentations may be helpful:
React Without ES6
Introducing JSX
React Without JSX
Edit: Also, I realized that React props usage may cause confusion for you. In react, the syntax of props usage again with curly braces but this is used to provide dynamic binding for your components. By using this syntax, your component will be able to update your html, if the value of your prop is changed. The following is the example of this case:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
For more detailed information, please examine the related React document for Component and Props usage.
Curly brace 2 contain the render() function's body.
Curly brace 1... actually also contains function's body, where the function is React.createClass(). This function takes as an argument an object, created with curly braces 1, containing functions and variables (in this case this object contains only render() method).
The truth is, that in this example the only JSX elements are<h1>Hello</h1>; and <MyCompClass />. They use JSX syntax, while with pure JS the createElement() and appendChild() DOM functions would be required.

Resources