Created
August 25, 2019 02:19
-
-
Save andrewfulton/eb8d96134e815b2062791c814f884bd6 to your computer and use it in GitHub Desktop.
I feel like I am so close to getting this...
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
import React, { useState, useCallback, useMemo } from 'react'; | |
// Everyone loves an increment clicker component. | |
const Component = ({ id, value, onClick}) => { | |
console.log(`Hello lets render component ${id}`); | |
return ( | |
<label>{value} | |
<button onClick={onClick}>Click</button> | |
</label> | |
); | |
} | |
// And we might love a memoized HOC version of | |
// it more (for later) | |
const MemoComponent = React.memo(Component); | |
const App = () => { | |
console.log('Its me, react, I am rendering App'); | |
const [v1, setV1] = useState(0); | |
const [v2, setV2] = useState(0); | |
// Using useCallback like this (without array of dependencies) | |
// will basically do nothing and serves no purpose? | |
// const CBincreaseV1 = useCallback(()=>{ setV1(v1+1) } ); | |
// const CBincreaseV2 = useCallback(()=>{ setV2(v2+1) } ); | |
// Using the following version we will get a new function each time the | |
// tracked variable changes: | |
// const CBincreaseV1 = useCallback(()=>{ setV1(v1+1) }, [v1] ); | |
// const CBincreaseV2 = useCallback(()=>{ setV2(v2+1) }, [v2] ); | |
// Which is probably fine OR we could use this form, | |
// where we pass a function to the stateSetter() | |
// and will get a cached version every subsequent render forever: | |
const CBincreaseV1 = useCallback(()=>{ setV1(c => c + 1) }, [] ); | |
const CBincreaseV2 = useCallback(()=>{ setV2(c => c + 1) }, [] ); | |
// the WRONG version of this looks like this, as the function is cached | |
// forever, the value of v1/v2 is trapped/baked in through JS function closures: | |
// const CBincreaseV1 = useCallback(()=>{ setV1(v1+1) }, [] ); | |
// const CBincreaseV2 = useCallback(()=>{ setV2(v2+1) }, [] ); | |
// So those seem functionally equivalent, depending on whether | |
// you have other needs w/r/t referential equality of the CBincrease | |
// between renders | |
// BUT either way, the components will re-render themselves all the time | |
// anyway, unless we make a memoized version of them? | |
// ie this will always re-render both components: | |
// return ( | |
// <> | |
// <Component id="One" value={v1} onClick={CBincreaseV1} /> | |
// <Component id="Two" value={v2} onClick={CBincreaseV2} /> | |
// </> | |
// ) | |
// SO THEN the following will only re-render the children where any of | |
// the relevant props change (no unnecessary renders). | |
// For large trees or complex components this may matter. Here is absolutely | |
// does not. | |
// ALSO this uses React.memo to make a HOC, not useMemo which | |
// seems to be an entirely different thing perhaps just a much | |
// simpler cache of values ? | |
// eg const cached = useMemo(() => runAGreatBigWeatherSimulationBasedOnMyPropForSomeReason(v1), [v1]); | |
return ( | |
<> | |
<MemoComponent id="One" value={v1} onClick={CBincreaseV1} /> | |
<MemoComponent id="Two" value={v2} onClick={CBincreaseV2} /> | |
</> | |
) | |
} | |
export default App; |
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
npx degit portablestudios/minimally-react usecallback | |
# replace App.jsx with the below | |
npm install && npm start | |
# What is the use case for useCallback without memoization? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment