Use of curly braces in React - reactjs

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.

Related

components in react are imported but not visible when used [duplicate]

I am playing around with the ReactJS framework on JSBin.
I have noticed that if my component name starts with a lowercase letter it does not work.
For instance the following does not render:
var fml = React.createClass({
render: function () {
return <a href='google.com'>Go</a>
}
});
React.render(<fml />, document.body);
But as soon as I replace the fml with Fml it does render.
Is there a reason I cannot begin tags with small letters?
In JSX, lower-case tag names are considered to be HTML tags. However, lower-case tag names with a dot (property accessor) aren't.
See HTML tags vs React Components.
<component /> compiles to React.createElement('component') (html tag)
<Component /> compiles to React.createElement(Component)
<obj.component /> compiles to React.createElement(obj.component)
#Alexandre Kirszenberg gave a very good answer, just wanted to add another detail.
React used to contain a whitelist of well-known element names like div etc, which it used to differentiate between DOM elements and React components.
But because maintaining that list isn't all that fun, and because web components makes it possible to create custom elements, they made it a rule that all React components must start with a upper case letter, or contain a dot.
From the official React reference:
When an element type starts with a lowercase letter, it refers to a built-in component like or and results in a string 'div' or 'span' passed to React.createElement. Types that start with a capital letter like compile to React.createElement(Foo) and correspond to a component defined or imported in your JavaScript file.
Also note that:
We recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.
Which means one has to use:
const Foo = foo; before using foo as a Component element in JSX.
The first part of a JSX tag determines the type of the React element, basically there is some convention Capitalized, lowercase, dot-notation.
Capitalized and dot-notation types indicate that the JSX tag is referring to a React component,
so if you use the JSX <Foo /> compile to React.createElement(Foo) OR <foo.bar /> compile to React.createElement(foo.bar) and correspond to a component defined or imported in your JavaScript file.
While the lowercase type indicate to a built-in component like <div> or <span> and results in a string 'div' or 'span' passed to React.createElement('div').
React recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter,
assign it to a capitalized variable before using it in JSX.
In JSX, React Classes are capitalized to make XML compatible, so that it is not mistaken for an HTML tag. If the react classes are not capitalized, it is an HTML tag as pre-defined JSX syntax.
User define components must be Capitalized
When an element type starts with a lowercase letter, it refers to a built-in component like <div> or <span> and results in a string 'div' or 'span' passed to React.createElement. Types that start with a capital letter like <Foo /> compile to React.createElement(Foo) and correspond to a component defined or imported in your JavaScript file.
React recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.
For example, this code will not run as expected:
import React from 'react';
// Wrong! This is a component and should have been capitalized:
function hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Wrong! React thinks <hello /> is an HTML tag because it's not capitalized:
return <hello toWhat="World" />;
}
To fix this, we will rename hello to Hello and use <Hello /> when
referring to it:
import React from 'react';
// Correct! This is a component and should be capitalized:
function Hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Correct! React knows <Hello /> is a component because it's capitalized.
return <Hello toWhat="World" />;
}
Here is the reference

REACT how come when we create a function called "App" the return html runs but doesn't work if any other? [duplicate]

I am playing around with the ReactJS framework on JSBin.
I have noticed that if my component name starts with a lowercase letter it does not work.
For instance the following does not render:
var fml = React.createClass({
render: function () {
return <a href='google.com'>Go</a>
}
});
React.render(<fml />, document.body);
But as soon as I replace the fml with Fml it does render.
Is there a reason I cannot begin tags with small letters?
In JSX, lower-case tag names are considered to be HTML tags. However, lower-case tag names with a dot (property accessor) aren't.
See HTML tags vs React Components.
<component /> compiles to React.createElement('component') (html tag)
<Component /> compiles to React.createElement(Component)
<obj.component /> compiles to React.createElement(obj.component)
#Alexandre Kirszenberg gave a very good answer, just wanted to add another detail.
React used to contain a whitelist of well-known element names like div etc, which it used to differentiate between DOM elements and React components.
But because maintaining that list isn't all that fun, and because web components makes it possible to create custom elements, they made it a rule that all React components must start with a upper case letter, or contain a dot.
From the official React reference:
When an element type starts with a lowercase letter, it refers to a built-in component like or and results in a string 'div' or 'span' passed to React.createElement. Types that start with a capital letter like compile to React.createElement(Foo) and correspond to a component defined or imported in your JavaScript file.
Also note that:
We recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.
Which means one has to use:
const Foo = foo; before using foo as a Component element in JSX.
The first part of a JSX tag determines the type of the React element, basically there is some convention Capitalized, lowercase, dot-notation.
Capitalized and dot-notation types indicate that the JSX tag is referring to a React component,
so if you use the JSX <Foo /> compile to React.createElement(Foo) OR <foo.bar /> compile to React.createElement(foo.bar) and correspond to a component defined or imported in your JavaScript file.
While the lowercase type indicate to a built-in component like <div> or <span> and results in a string 'div' or 'span' passed to React.createElement('div').
React recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter,
assign it to a capitalized variable before using it in JSX.
In JSX, React Classes are capitalized to make XML compatible, so that it is not mistaken for an HTML tag. If the react classes are not capitalized, it is an HTML tag as pre-defined JSX syntax.
User define components must be Capitalized
When an element type starts with a lowercase letter, it refers to a built-in component like <div> or <span> and results in a string 'div' or 'span' passed to React.createElement. Types that start with a capital letter like <Foo /> compile to React.createElement(Foo) and correspond to a component defined or imported in your JavaScript file.
React recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.
For example, this code will not run as expected:
import React from 'react';
// Wrong! This is a component and should have been capitalized:
function hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Wrong! React thinks <hello /> is an HTML tag because it's not capitalized:
return <hello toWhat="World" />;
}
To fix this, we will rename hello to Hello and use <Hello /> when
referring to it:
import React from 'react';
// Correct! This is a component and should be capitalized:
function Hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Correct! React knows <Hello /> is a component because it's capitalized.
return <Hello toWhat="World" />;
}
Here is the reference

Arguments instead of Props in React Functional Component

Is this function correct React Functional Component? Or why should I use props object?
function StyledLabel(value, cssClass){
return <span className={cssClass}>{value}</span>
}
Only difference I see is in calling this function:
<App>
{StyledLabel(value, cssClass)}
</App>
function StyledLabel(value, cssClass){
return <span className={cssClass}>{value}</span>
}
being used like
{StyledLabel(value, cssClass)}
isn't a traditional functional component but a function that returns JSX.
If you follow such a syntax, you won't be able to leverage some functionalities of a functional component such as using React.memo.
Although you can still use hooks within the functional component.
The other drawback of using such a syntax is that you cannot easily add children components to StyledLabel like you do with the following syntax
<StyledLabel>
<SomeChild/>
</StyledLabel>
Although internally React too invokes the function by calling it and JSX render is a just a Syntactic Sugar that uses React.createElement to transpile it but it provides you with a way to make the component a part of the Virtual DOM instead of its return value being part of virtual dom
Function Component is a function which returns JSX element.
That's a Function Component which invoked as a normal function.
But in this case is hasn't invoked with React.createElement.
Because JSX is syntactic sugar for React.createElement, you need to invoke the function with JSX syntax like so:
function StyledLabel({ value, cssClass }) {
return <span className={cssClass}>{value}</span>;
}
<App>
<StyledLabel value={value} cssClass={cssClass} />
</App>
Without invoking React.createElement, React won't be aware of the component (for state updates, diffing algorithm etc.), as it will be just a normal function call.
Yet another major problem is the function arguments:
// Not function StyledLabel(value, cssClass)
function StyledLabel(props)
React.createElement accepts a single argument which is the component's props.
React.createElement API
React.createElement(
type,
[props],
[...children]
)

Babel does not transpile a JSX instance of an arrow function

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)

Output object name other than React with jsx syntax

with React v0.12 the #jsx pragma is gone which means it is no longer possible to output jsx with anything other than the React.METHODNAME syntax.
For my use case I am trying to wrap the React object in another object to provide some convenience methods thus, in my component files, I want to be able to write:
var myConvenienceObject = require('React-Wrapper');
var Component = myConvenienceObject.createSpecializedClass({
render: function () {
return <div />
}
})
However the jsx compiler automatially converts <div /> into React.createElement("div", null)
With older versions of React it was possible to handle this using the pragma at the top of the file. However, since that has been removed, I was wondering if there was any way currently to change the name of the object compiled by jsx so <div /> would be transformed into myConvenienceObject.createElement("div", null)
No, it's no longer possible to use a custom prefix for JSX. If you need to do this, you'll need to modify the JSX transform code, or create a fake React.
var React = require('react'), FakeReact = Object.assign({}, React, {
createElement: function(component, props, ...children){
// ...
// eventually call the real one
return React.createElement(component, props, ...children);
}
});
module.exports = FakeReact;
And then to use it you import the fake react and call it React.
var React = require('fake-react');
// ...
render: function(){ return <div />; }
If you would like to make some elements contains in your myConvenienceObject, you could consider the children props as shown in the doc. But this may need some changes in the myConvenienceObject too, to accept the children.
By the way, i'm not sure where is this createSpecializedClass functions comes from and what it does

Resources