What difference you see between regular/arrow functions and react functional component
React functional component
import React from 'react';
function MyComp(){
return <span>test</span>
}
Regular function
function myFun(){
return null;
}
Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called props) and return React elements describing what should appear on the screen.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
From a JavaScript perspective, this is nothing but a function, except for a special return. It's JSX and each JSX element is just syntactic sugar for calling React.createElement(component, props, ...children).
Basically, you can replace the JSX in the example above with something like:
React.createElement('h1', null, `Hello ${props.name}`);
And this is nothing but a JavaScript :)
And then you can render your component:
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
You call ReactDOM.render() with the <Welcome name="Sara" /> element.
React calls the Welcome component with {name: 'Sara'} as the props.
Our Welcome component returns a <h1>Hello, Sara</h1> element as the result.
React DOM efficiently updates the DOM to match <h1>Hello, Sara</h1> and you get it on the screen.
There is one important requirement for React functional component!
Always start component names with a capital letter.
React treats components starting with lowercase letters as DOM tags. For example, represents an HTML div tag, but represents a component and requires Welcome to be in scope.
This function from your example can be used as a functional component:
function MyFun() { // name should start with a capital
return null;
}
React won't display anything because React does not render if component returns null.
Related
Why does 'element' define what looks like an HTML tag that call's a function.
Why would i not set element to something like: Welcome('Sara')
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
The format resembling HTML is called JSX:
it is a syntax extension to JavaScript. We recommend using it with
React to describe what the UI should look like
Technically (in this simple case) you could replace the JSX with Welcome({ name: 'Sara' }), but that is not the standard way to render components in React - and it has some technical implications because it is not the same as using JSX (which calls React.createElement).
I am wondering what the effects of coupling / nesting a functional component inside a React class component without explicitly passing props to it via params and using this.props via the parent class are. I understand that having a functional component outside of the React class component is easier to test and read, but am curious to know what the exact difference between using this.props vs props via params are in terms of performance / renders.
For example:
class Foo extends React.Component {
bar = () => { return (<p>{this.props.baz}</p>) }
render() {
return (
<h1>Hello, {this.props.name}</h1>
{this.bar()}
)
}
}
Vs.
class Foo extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
<Bar baz={'foobar'}
)
}
}
function Bar(props) {
return <p>{props.baz}</p>
}
Both give the same result except when you care about code reusability.
If you care about reusing the Bar function then you better keep it outside the class so you can import it elsewhere.
Example:
If Bar renders a success or warning message. you'll want to keep the same design for all warning messages in the system.
Now if every component has its own warning message code, you'll not be able to edit the warning message design easily also you'll have to keep rewriting the same code over and over again.
To get straight to the point, in a react class based component where does the prop object come from?
I am following the official React tic-tac-toe game tutorial.
Firstly, when I take a look at the code for the react Component class (which we extend when creating a React component) I observe that the function has 3 parameters Component(props, context, updater) but I am puzzled as to why in the cases where super() is called only props is passed like so super(props).
Shouldn't there be values passed for context and updater also? Why is it that there are no errors when the code is run without super being called?
import React, { Component } from "react";
export class Square extends Component
{
render()
{
return (
<span>
<button className="square" onClick={ () => { alert("click") } }>
{this.props.value}
</button>
</span>
)
}
}
To be clear, I understand that the value property in {this.props.value} comes from the property passed to Square <Square value={index}/>; which is a child in another component (Board in the case of the React tutorial) but this is not what I'am referring to.
Props are the properties that are passed from the Super class to the class you create using extends Components in React.
Similar to what happens in OOPS where the parent class properties are passed to the children in the constructor . similar way the props are passed in React this applies in case of functional components too
Note - Please do not confuse it with OOPS concepts [ just to give a
Oversimplified version]
One thing is necessary: the parent's (which is Component class) constructor must be invoked within any React class component.
What super does (inside Square's constructor) is to invoke Component's constructor with Square's props. (Hope it's not complicated)
If Square has a constructor then you should call super implicitly.
If Square doesn't have a constructor, then Component's constructor will automatically be invoked when using <Square />.
Also you don't use context or updater directly in your components. So there is no need to define them there.
I can define a component like this:
class Welcome extends React.Component {
render() {
return <h1>Hello!</h1>;
}
}
When I want to render this object in the Dom (or rather add it to the virtual DOM) I call
ReactDOM.render(
<Welcome />,
document.getElementById('root')
);
That means that at some point multiple .render() functions are nested inside of each other since we defined return <h1>Hello!</h1>; inside of the .render() function of Welcome.
It also means that I can use the .render() method to render an Object to the DOM and to define a new react object.
This syntax is from the official documentation
Does .render() just render things to the virtual DOM and the nesting is resolved by React internally or is there more behind it?
From Rendering a Component:
(updated to reflect your code)
class Welcome extends React.Component {
render() {
return <h1>Hello!</h1>;
}
}
ReactDOM.render(
<Welcome />,
document.getElementById('root')
);
We call ReactDOM.render() with the <Welcome /> element.
React calls the Welcome component with {} as the props.
Our Welcome component returns a <h1>Hello!</h1> element as the result.
React DOM efficiently updates the DOM to match <h1>Hello</h1>.
It may be beneficial to read up on the React Life Cycle.
To understand render you have to understand how react works internally. To understand this in greater detail I would recoment reading this but here is a quick overview:
Conceptually a react component is a just a function that returns an Object like this:
{
type: 'button',
props: {...}
};
So the render() part of a class component just specifies what part of the component will be returned. The react virtual dom is made up of many of these object nested inside of each other (in props.children). React will start at the top object, turn it into an html node and render it to the dom, then do the same for all of its children etc.
TL;DR Given the following example code:
ReactDOM.render(<MyComponent prop1={someVar} />, someDomNode);
Is it possible to manually pass React context into the instance of MyComponent?
I know this sounds like a weird question given React's nature, but the use case is that I'm mixing React with Semantic UI (SUI) and this specific case is lazy-loading the contents of a SUI tooltip (the contents of the tooltip is a React component using the same code pattern as above) when the tooltip first displays. So it's not a React component being implicitly created by another React component, which seems to break context chain.
I'm wondering if I can manually keep the context chain going rather than having components that need to look for certain data in context AND props.
React version: 0.14.8
No. Before react 0.14 there was method React.withContext, but it was removed.
However you can do it by creating HoC component with context, it would be something like:
import React from 'react';
function createContextProvider(context){
class ContextProvider extends React.Component {
getChildContext() {
return context;
}
render() {
return this.props.children;
}
}
ContextProvider.childContextTypes = {};
Object.keys(context).forEach(key => {
ContextProvider.childContextTypes[key] = React.PropTypes.any.isRequired;
});
return ContextProvider;
}
And use it as following:
const ContextProvider = createContextProvider(context);
ReactDOM.render(
<ContextProvider>
<MyComponent prop1={someVar} />
</ContextProvider>,
someDomNode
);
In React 15 and earlier you can use ReactDOM.unstable_renderSubtreeIntoContainer instead of ReactDOM.render. The first argument is the component who's context you want to propagate (generally this)
In React 16 and later there's the "Portal" API: https://reactjs.org/docs/portals.html