21
loading...
This website collects cookies to deliver better user experience
import React from 'react';
class App extends React.Component {
render() {
return <h1>Hello, World!</h1>;
}
}
import React from 'react';
function App() {
return <h1>Hello, World!</h1>;
}
render
keyword. React.Component
class in class component?React.Component
class, it allows us to pass props to a user defined class/component and inherit methods from React.Component
class, like the lifecycle methods (componentDidMount
, componentDidUpdate
, componentWillUnmount
, render
) and setState
.render
is one of the lifecycle methods and the only required method in a class component. It would examine this.props
and this.state
and return types like React elements (JSX), array and fragments, etc. Do not expect it will modify component state! render
method, as well as the rest of the lifecycle methods. hereuseState
and useEffect
for lifecycle methods (will cover that in a bit!).name
from this Component
: <ExampleComponent name="Megan" />
class ExampleComponent extends React.Component {
render() {
const { name } = this.props;
return <h1>Hello, { name }!</h1>
// or without destructuring, it will look like this:
// return <h1>Hello, { this.props.name }!</h1>
}
}
// with destructuring
const ExampleComponent = ({ name }) => {
return <h1>Hello, { name }!</h1>
}
// without destructuring
const ExampleComponent = (props) => {
return <h1>Hello, { props.name }!</h1>
}
this
to refer to the props, or we can destructure it to get name
inside props. Or if we have multiple props, we can do that too:class ExampleComponent extends React.Component {
render() {
const { name, age, occupation } = this.props;
return (
<div>
<h1>Hello, { name }!</h1>
<p>I am { age } yo and I work as a { occupation }.</p>
</div>
)
}
// with destructuring
const ExampleComponent = ({ name, age, occupation }) => {
return (
<div>
<h1>Hello, { name }!</h1>
<p>I am { age } yo and I work as a { occupation }.</p>
</div>
)
}
// without destructuring
const ExampleComponent = (props) => {
return return (
<div>
<h1>Hello, { props.name }!</h1>
<p>I am { props.age } yo and I work as a { props.occupation }.</p>
</div>
)
}
useState
in React 16.8, we can handle state in functional component! yay! class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
name: "Megan"
};
}
// or you can write this without constructor():
// state = {
// count: 0,
// name: "Megan"
// };
render() {
return (
<div>
<h1>Hello, {this.state.name}</h1>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click to add 1
</button>
</div>
)
}
}
onClick
event before render()
:class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
name: "Megan"
};
}
// or you can write this without constructor():
// state = {
// count: 0,
// name: "Megan"
// };
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<h1>Hello, {this.state.name}</h1>
<button onClick={this.handleClick}>
// or <button onClick={() => this.handleClick()}>
Click to add 1
</button>
</div>
)
}
}
// by the way, I don't want to continue this without explanation
// This is the arrow function, in case you are not familiar
// Alternatively, you can also write
// function ExampleComponent()
// They are basically the same thing.
import React, { useState } from 'react';
// ES6 destructure ^
const ExampleComponent = () => {
const [count, setCount] = useState(0);
// or without destructuring, this will be React.useState(0)
return (
<div>
<h1>Hello, {this.state.name}</h1>
<button onClick={this.handleClick}>
// or <button onClick={() => setCount(count + 1)}>
Click to add 1
</button>
</div>
)
}
this.state
inside JSX and we would use setState
to update the value of the state. You can set the function inside the event or outside of the render() method -- for readability.useState
to assign initial state and we would use setCount
(in our example) to update the state. If we want to access the value of the state, we can omit this.state
and call the name of the state instead, in our case, it would just be count
.[count, setCount]
? [count, setCount]
syntax is called "array destructuring"!! We are basically making two new variables, in other words,let countVariable = useState(0);
let count = countVariable[0];
let setCount = countVariable[1];
0
and 1
as they have a specific meaning, so React use the "array destructuring" instead. useEffect
is the combination of componentDidMount
, componentDidUpdate
and componentWillUnmount
. componentDidMount
class ExampleComponent extends React.Component {
this.state = {
data: []
}
componentDidMount() {
fetch(someUrlHere)
.then(res => res.json())
.then(data => this.setState(data))
}
render() {
...
}
}
const ExampleComponent = () => {
const [data, setData] = useState([]);
useEffect(() => {
fetch(someUrlHere)
.then(res => res.json())
.then(data => setData(data))
}, []);
return (
...
)
}
componentDidMount
is only called once after the first render.componentDidMount
with useEffect
. As we can see there's a []
in the second argument, we usually would put some state we like to update/change, let's say you want to restart a quiz app. useEffect
will only be called if there's any selected changes. useEffect
will be called once on mounting, similar to componentDidMount
.componentDidUpdate()
and useEffect()
. If you are interested, I am attaching this link from React Doc, this Stack Overflow post and How to mimic componentDidUpdate() with React Hooks from another dev.to writer. Based on my quick research, it looks like we may need useRef()
and custom hook, which currently is out of my knowledge range at the moment.👩🏻💻 componentWillUnmount
clearInterval
duh).class ExampleComponent extends React.Component {
this.state = {
data: []
}
// say we have a mounted function that returns a boolean
mounted = () => {
...
}
componentDidMount() {
this.mounted = true;
fetch(someUrlHere)
.then(res => res.json())
.then(data => {
if (this.mounted)) {
this.setState(data)
}
})
}
componentWillUnmount() {
this.mounted = false;
}
render() {
...
}
}
const ExampleComponent = () => {
const [data, setData] = useState([]);
useEffect(() => {
let isMounted = true;
request.get(url)
.then(result => {
if (isMounted) {
setData(result);
}
});
return () => {
isMounted = false;
};
}, []);
return (
...
)
}
useEffect
is that you can write functions for both mounting and unmounting in the same place. componentWillUnmount
is useful when doing cleanups as mentioned above, without that, it can cause severe memory leaks on a bigger project.