import React, { useState } from 'react'
function Example() {
// Declare a new state, we can have more than one
const [count, setCount] = useState(0) // Initial state
const [user, setUser] = useState({ name: 'Joni' lastName: 'del Valle' })
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Change Count
</button>
<p>User: {user.name} {user.lastName}</p>
<button onClick={() => setUser({...user, name: 'Ariel' })}>
Change User
</button>
</div>
);
}
export default Example
//Class
import React, { Component } from 'react'
class CounterButton extends Component {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return <button onClick={() => this.setState({ count: this.state.count + 1 })}>
{ this.state.count }
</button>
}
}
export default CounterButton
//Hooks
import React, { useState } from 'react'
const CounterButton = props => {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>
{ count }
</button>
}
export default CounterButton
//Class
import React, { Component } from 'react'
class ClassComponent extends Component {
componentDidUpdate() {
console.log('Just updated...')
}
render() {
return <div>Class Component</div>
}
}
export default ClassComponent
//Hooks
import React, { useEffect } from 'react'
const FunctionalComponent = props => {
useEffect(() => {
console.log('Just updated...')
})
return <div>Functional Component </div>
}
export default FunctionalComponent
//Class
import React, { Component } from 'react'
class ClassComponent extends Component {
componentDidMount() {
console.log('I just mounted!')
}
render() {
return <div>Class Component</div>
}
}
export default ClassComponent
//Hooks
import React, { useEffect } from 'react'
const FunctionalComponent = props => {
useEffect(() => {
console.log('I just mounted!')
}, [])
return <div>Functional Component </div>
}
export default FunctionalComponent
//Class
import React, { Component } from 'react'
class ClassComponent extends Component {
componentWillUnmount() {
console.log('I am unmounting!')
}
render() {
return <div>Class Component</div>
}
}
export default ClassComponent
//Hooks
import React, { useEffect } from 'react'
const FunctionalComponent = props => {
useEffect(() => {
return () => console.log('I am unmounting')
}, [])
return <div>Functional Component </div>
}
export default FunctionalComponent
//Class
import React, { Component } from 'react'
class ClassComponent extends Component {
componentWillReceiveProps(nextProps) {
if (nextProps.count !== this.props.count) {
console.log('count changed', nextProps.count)
}
}
render() {
return <div>Class Component</div>
}
}
export default ClassComponent
//Hooks
import React, { useEffect } from 'react'
const FunctionalComponent = props => {
useEffect(() => {
console.log('count changed', props.count);
}, [props.count])
return <div>Functional Component </div>
}
export default FunctionalComponent
import React, { Component } from 'react' //Class
class ClassComponent extends Component {
constructor() {
super()
this.inputRef = null
}
render() {
return <>
<input ref={inputRef => { this.inputRef = inputRef }} />
<button onClick={() => this.inputRef.focus()}>
Focus the input
</button>
</>
}
}
export default ClassComponent
import React, { useRef } from 'react' //Hooks
const FunctionalComponent = props => {
const inputRef = useRef()
return <>
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
Focus the input
</button>
</>
}
export default FunctionalComponent
import React, { Component } from 'react' //Class
class ClassComponent extends Component {
shouldComponentUpdate(nextProps) {
return nextProps.count !== this.props.count
}
render() {
return <div>Class Component</div>
}
}
export default ClassComponent
import React, { memo } from 'react' //Hooks
const FunctionalComponent = props => {
return <div>Functional Component</div>
}
const MyFunctionalComponent = memo(
FunctionalComponent,
(prevProps, nextProps) => nextProps.count !== prevProps.count
)
export default MyFunctionalComponent
We gonna use memo for this one, while this is not a Hook, it’s still part of the class-to-functional-component migration plan
const Timer = (props) => {
const intervalRef = useRef();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
}
useRef has another cool usage besides DOM refs, it is also a generic container whose current property is mutable and can hold any value, similar to an instance property on a class
const Counter = props => {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
return <h1>Now: {count}, before: {prevCount}</h1>;
}
Some lifecycle method, like componentDidUpdate, provide the previous state and props. If you really need the previous values for your Hooks, this can be imitated the following way (using yet again our good friend – useRef)