ReactJS Terms and Key Components - rimander123/react-js-training-course GitHub Wiki
ReactJS renders HTML to the web page by using a function called ReactDOM.render(), this function takes two arguments, HTML code and an HTML element. The purpose of the function is to display the specified HTML code inside the specified HTML element.
Display a paragraph inside the "root" element:
ReactDOM.render(<p>Hello</p>, document.getElementById('root'));The result is displayed in the <div id="root"> element:
<body>
<div id="root"></div>
</body>JSX allows us to write HTML elements in JavaScript and place them in the DOM without any createElement() and/or appendChild() methods. JSX converts HTML tags into react elements.
With JSX you can write expressions inside curly braces { }.
The expression can be a React variable, or property, or any other valid JavaScript expression. JSX will execute the expression and return the result:
Example
Execute the expression 5 + 5:
const myelement = <h1>React is {5 + 5} times better with JSX</h1>;
ReactDOM.render(myelement, document.getElementById('root'));To write HTML on multiple lines, put the HTML inside parentheses:
Example
Create a variable that contains HTML code and display it in the root node:
const myelement = (
<table>
<tr>
<th>Name</th>
</tr>
<tr>
<td>John</td>
</tr>
<tr>
<td>Elsa</td>
</tr>
</table>
);
ReactDOM.render(myelement, document.getElementById('root'));The HTML code must be wrapped in ONE top level element.
So if you like to write two headers, you must put them inside a parent element, like a div element.
Example
Wrap two headers inside one DIV element:
const myelement = (
<div>
<h1>I am a Header.</h1>
<h1>I am a Header too.</h1>
</div>
);For more Information see: JSX, W3Schools JSX
Components are independent and reusable bits of code. They serve the same purpose as JavaScript functions, but work in isolation and returns HTML via a render function. Components come in two types, Class components and Function components.
Class component must extend from React.Component, and require to use this statement to access functions and members.
class NewClassComponent extends React.Component {
// javascript function definitions goes here
// const/let declaration aren't allowed here
render() {
// javascript template manipulation stuff goes here
// const/let declaration allowed
return (
// template goes here
<span>This is a New Class Component</span>
);
}
}Function Components should be as simple as possible and don't require to use this statement to access functions and members. The only method you must define in a React.Component subclass is called render().
function NewFunctionComponent() {
// javascript stuff goes here
return (
// template goes here
<span>This is a New Function Component</span>
);
}
const NewFunctionComponent = () => {
// javascript stuff goes here
return (
// template goes here
<span>This is a New Function Component</span>
);
}Props are like function arguments in JavaScript and attributes in HTML.
To send props into a component, use the same syntax as HTML attributes:
Example
Add a "brand" attribute to the Car element:
const myelement = <Car brand="Ford" />;The component receives the argument as a props object:
Example
Use the brand attribute in the component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand}!</h1>;
}
}If you have a variable to send, and not a string as in the example above, you just put the variable name inside curly brackets:
Example
Create a variable named "carname" and send it to the Car component:
class Car extends React.Component {
render() {
return <h2>I am a {this.props.brand}!</h2>;
}
}
class Garage extends React.Component {
render() {
const carname = "Ford";
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand={carname} />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));Like props, state holds information about the component. However, the kind of information and how it is handled is different.
By default, a component has no state. The Welcome component from above is stateless:
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
}So when would you use state?
When a component needs to keep track of information between renderings the component itself can create, update, and use state.
Example
We’ve got a button that keeps track of how many times you’ve clicked it.
class Button extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}setState() schedules an update to a component’s state object. When state changes, the component responds by re-rendering.
Calls to setState() are asynchronous - don’t rely on this.state to reflect the new value immediately after calling setState.
Example
incrementCount() {
// Note: this will *not* work as intended.
this.setState({count: this.state.count + 1});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// When React re-renders the component, `this.state.count` will be 1, but you expected 3.
// This is because `incrementCount()` function above reads from `this.state.count`,
// but React doesn't update `this.state.count` until the component is re-rendered.
// So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.
}To fix this you need to pass an updater function instead of an object if you need to compute values based on the current state. Passing an update function allows you to access the current state value inside the updater. Since setState() calls are batched, this lets you chain updates and ensure they build on top of each other instead of conflicting:
Example
incrementCount() {
this.setState((state) => {
// Important: read `state` instead of `this.state` when updating.
return {count: state.count + 1}
});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// If you read `this.state.count` now, it would still be 0.
// But when React re-renders the component, it will be 3.
}Each component has several lifecycle methods that you can override to run code at particular times in the process. You can use this lifecycle diagram as a cheat sheet.
For more information see
The render() method is the only required method in a class component. The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.
The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.
Typically, in React constructors are only used for two purposes:
- Initializing local state by assigning an object to this.state.
- Binding event handler methods to an instance.
You should not call setState() in the constructor(). Instead, if your component needs to use local state, assign the initial state to this.state directly in the constructor:
constructor(props) {
super(props);
// Don't call this.setState() here!
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}Constructor is the only place where you should assign this.state directly. In all other methods, you need to use this.setState() instead.
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
This method is a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe in componentWillUnmount().
You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state.
componentDidUpdate(prevProps, prevState, snapshot) is invoked immediately after updating occurs. This method is not called for the initial render.
Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}You may call setState() immediately in componentDidUpdate() but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop.
componentWillUnmount() is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount().
You should not call setState() in componentWillUnmount() because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again.
There are more Lifecycle Methods, they’re handy once in a while, but most of your components probably don’t need any of them.
If you’re interested in playing around with React and JSX, you can use an online code playground.
- React Component: https://reactjs.org/docs/react-component.html
- State & Lifecycle: https://reactjs.org/docs/state-and-lifecycle.html