Reputation: 6904
This is not for behavior but syntax.
The syntax is the same for both, I can very well create a random function that takes an argument named props, but will React take it and do its virtual DOM thing with that function? OR it might be checking if that function is returning JSX , but when does this check happen ?
As react is just a library when does this static differentiation of which function is a component and which is not happen?
Any reference to documentation will help.
Upvotes: 2
Views: 1733
Reputation: 6056
React does not do any static analysis to determine if a function is a component.
Instead, React will do "it's virtual DOM thing" (and all the other magic like lifecycles) if the function returns a valid React element.
React throws an error if the function doesn't return a React element.
https://reactjs.org/docs/components-and-props.html:
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions.
Technically React doesn't need any functional or class components at all.
Consider this example, without any components or functions:
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
React.createElement( 'div', null, [
React.createElement( 'h1', null, 'React without any functions' ),
React.createElement( 'p', null, 'Technically you don\'t need to pass functions to React.' ),
]),
document.getElementById('root')
);
This quickly becomes cumbersome.
So one might have the idea to separate the code into "parts" by using functions which return these parts instead, e.g.:
const Headline = function(){
return React.createElement( 'h1', null, 'React with "factory functions"' );
};
const Content = function(){
return React.createElement( 'p', null, 'You might want to separate stuff using functions.' );
};
const Page = function(){
return React.createElement( 'div', null, [
Headline(),
Content()
]);
};
ReactDOM.render(
Page(),
document.getElementById('root')
);
Note that these are just normal javascript functions, no "magic" at all.
If your function doesn't return a valid ReactElement, then React just throws an error, e.g.:
const Page = function(){
return { notAValidReactElement: 'this is not a valid react element' };
};
ReactDOM.render(
Page(), // ---> Uncaught Error: Objects are not valid as a React child ...
document.getElementById('root')
);
But this is not optimal, e.g. all .createElement()
methods are still always executed at the same time.
The React people had similar ideas, so React accepts a function name
as type
parameter (instead of e.g. 'h1'
), and uses that function like a callback, so that React can decide e.g. if the function
actually needs to be executed, or can be skipped:
const Page = function(){
return React.createElement( 'div', null, [
React.createElement( Headline, null, [] ),
React.createElement( Content, null, [] )
]);
}
These are still the same functions as before. They just work because we wrote them so that they return a correct value.
This is actually more or less the full story regarding this topic, but people might also be confused why I am
talking about React.createElement( Page, ...
, while we are normally using something like <Page>...
.
So ...
One might have the idea to shorten the React.createElement
a bit, for less typing, e.g.:
const CE = function( type, props, childs ){
return React.createElement( type, props, childs );
};
ReactDOM.render(
CE( 'div', null, [
CE( 'h1', null, 'React without any functions' ),
CE( 'p', null, [
CE('b', null, 'Nice'),
' if we can shorten the code a bit.',
] ),
]),
document.getElementById('root')
);
Luckily smart people have had this idea already, so you can use JSX instead, e.g.:
ReactDOM.render(
<div>
<h1>React without any functions</h1>
<p>
<b>Even nicer: </b>
we can just use JSX!
</p>
</div>,
document.getElementById('root')
);
That's just a different syntax, that gets converted into javascript at build time.
(Maybe also have a look at Hyperscript for comparison and background understanding.)
Upvotes: 1