Skip to content

Instantly share code, notes, and snippets.

@dillonhafer
Created August 6, 2019 19:13
Show Gist options
  • Save dillonhafer/0948aae3ecd08cf44917207ac1f479ec to your computer and use it in GitHub Desktop.
Save dillonhafer/0948aae3ecd08cf44917207ac1f479ec to your computer and use it in GitHub Desktop.
How to use useCallback with memoized functions
// Taken from https://codesandbox.io/s/usecallback-hooks-vs-class-i1efp
import React, { useRef, useCallback, useState } from 'react'
import ReactDOM from 'react-dom'
import faker from 'faker'
import equal from 'fast-deep-equal'
import times from 'lodash/times'
import './styles.css'
const initialState = times(200, i => ({
id: i,
checked: false,
name: faker.fake('{{name.firstName}}'),
}))
const shouldSkipUpdate = (next, prev) => {
return equal(prev.item, next.item) && next.setChecked === prev.setChecked
}
const Child = React.memo(({ item, setChecked }) => {
console.log('child rendered ', item.id)
return (
<button
style={{
backgroundColor: item.checked ? 'blue' : undefined,
fontSize: 16,
margin: 4,
padding: 4,
}}
onClick={() => {
setChecked(item)
}}
>
{item.name} {Date.now()}
</button>
)
}, shouldSkipUpdate)
function ParentFunction() {
const [list, setList] = useState(initialState)
const setChecked = useCallback(
item => {
setList(prevList =>
prevList.map(i => {
if (i.id === item.id) {
return { ...i, checked: !i.checked }
}
return i
}),
)
},
[setList],
)
console.log('Parent Function')
return (
<div className="App">
{list.map(item => (
<Child key={item.id} item={item} setChecked={setChecked} />
))}
</div>
)
}
class ParentKlazz extends React.Component {
state = {
list: initialState,
}
setChecked = item => {
this.setState(prevState => ({
list: prevState.list.map(i => {
if (i.id === item.id) {
return { ...i, checked: !i.checked }
}
return i
}),
}))
}
render() {
const {
state: { list },
} = this
console.log('Parent Klazz', list, this.state.list)
return (
<div className="App">
{list.map(item => (
<Child key={item.id} item={item} setChecked={this.setChecked} />
))}
</div>
)
}
}
function App() {
return (
<div>
<h1>Function</h1>
<ParentFunction />
<hr />
<h1>Class</h1>
<ParentKlazz />
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment