Created
August 6, 2019 19:13
-
-
Save dillonhafer/0948aae3ecd08cf44917207ac1f479ec to your computer and use it in GitHub Desktop.
How to use useCallback with memoized functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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