A guide/cheatsheet to help you migrate from ES6 class components to the React Hooks API.
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}
increment() {
this.setState(prevState => ({ count: (prevState.count += 1) }));
}
decrement() {
this.setState(prevState => ({ count: (prevState.count -= 1) }));
}
render() {
return (
<div>
<div>{this.state.count}</div>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</div>
);
}
}
import React, { useState } from "react";
function Counter () {
const [count, setCount] = useState(0);
return (
<div>
<div>{count}</div>
<button onClick={() => setCount(count => count + 1)}>Increment</button>
<button onClick={() => setCount(count => count - 1)}>Decrement</button>
</div>
);
}
import React from "react";
class Clicker extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
alert(`You just clicked ${this.props.id}`);
event.stopPropagation();
}
render() {
return <div onClick={this.handleClick}>Click me!</div>;
}
}
import React, { useCallback } from 'react';
function Clicker({ id }) {
const handleClick = useCallback(
event => {
alert(`You just clicked ${id}`);
event.stopPropagation();
},
[id]
);
return <div onClick={handleClick}>Click me!</div>;
}
import React from "react";
function fetchFakeData() {
return new Promise(resolve => {
setTimeout(() => {
resolve([{ id: 1, name: "Foo" }, { id: 2, name: "Bar" }]);
}, 1000);
});
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
componentDidMount() {
fetchFakeData().then(fakeData => this.setState({ data: fakeData }));
}
render() {
return (
<div>
{this.state.data.length === 0
? "Loading..."
: this.state.data.map(({ id, name }) => <span key={id}>{name}</span>)}
</div>
);
}
}
function fetchFakeData() {
return new Promise(resolve => {
setTimeout(() => {
resolve([{ id: 1, name: "Foo" }, { id: 2, name: "Bar" }]);
}, 1000);
});
}
function App() {
const [data, setData] = useState([]);
useEffect(() => {
fetchFakeData().then(fakeData => setData(fakeData));
}, []);
return (
<div>
{data.length === 0
? "Loading..."
: data.map(({ id, name }) => <span key={id}>{name}</span>)}
</div>
);
}
function makeRandNumWith(a, b) {
return Math.floor(Math.random() * b) + a;
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
parentCount: 0
};
}
render() {
return (
<div>
<span>Parent count: {this.state.parentCount}</span>
<button
onClick={() => this.setState({ parentCount: makeRandNumWith(0, 10) })}
>
Randomize & Sync
</button>
<Child parentCount={this.state.parentCount} />
</div>
);
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
childCount: props.parentCount
};
}
componentDidUpdate(prevProps) {
if (prevProps.parentCount !== this.props.parentCount) {
this.setState({ childCount: this.props.parentCount });
}
}
render() {
return (
<div>
<span>Child count: {this.state.childCount}</span>
<button
onClick={() =>
this.setState(prevState => ({
childCount: prevState.childCount + 1
}))
}
>
Increment Child Count
</button>
</div>
);
}
}
import { useEffect, useState } from "react";
function makeRandNumWith(a, b) {
return Math.floor(Math.random() * b) + a;
}
function Parent() {
const [parentCount, setParentCount] = useState(0);
return (
<div>
<span>Parent count: {parentCount}</span>
<button onClick={() => setParentCount(makeRandNumWith(0, 10))}>
Randomize & Sync
</button>
<Child parentCount={parentCount} />
</div>
);
}
function Child({ parentCount }) {
const [childCount, setChildCount] = useState(parentCount);
useEffect(() => {
setChildCount(parentCount);
}, [parentCount]);
return (
<div>
<span>Child count: {childCount}</span>
<button onClick={() => setChildCount(x => x + 1)}>
Increment Child Count
</button>
</div>
);
}