type Reducer: (state: any, action?: any) => void
type Dispatch: (action?: any) => void
function useReducer (reducer: Reducer, initialState: any) [state: any, dispatch: Dispatch] {
return [initialState, function(action?: any) {
reducer(initialState, action)
}]
}
function Xyz() {
const [count, setCount] = useState(0)
const childFunc = () => {}
return (
<ComponentThatWillRerender />
<Component x={childFunc} c={count} onClick={()=>setCount(count+1)}/> #here when ComponentThatWillRerender rerenders, childFunc is recreated, i.e change, hence Component is recreated with new props, so it has to rerender, which is not expected because Component doesnt change
)
}
===============> useCallback
function Xyz() {
const [count, setCount] = useState(0)
const childFunc = useCallback(()=> () => {}) //cached unless count changes
return (
<ComponentThatWillRerender />
<Component x={childFunc} c={count} onClick={()=>setCount(count+1)} /> #here when ComponentThatWillRerender rerenders, childFunc is cached, so Component is not rendered again
)
}
function Xyz() {
const [count, setCount] = useState(0)
const expensiveComponentRunsWhenCountChange = function() {
let num = 1 + ... + 1 billion
return num
}
return (
<ComponentThatWillRerender />
{expensiveComponentRunsWhenCountChange} #here when ComponentThatWillRerender rerenders, expensiveComponent is recreated, which is not expected as count has not changed
<Count x={count} onClick={()=>setCount(count+1)}/>
)
}
===================>useMemo
function Xyz() {
const [count, setCount] = useState(0)
const expensiveComponentRunsWhenCountChange = useMemo(()=> function() {
let num = 1 + ... + 1 billion
return num
},[count]) //cached unless count changes
return (
<ComponentThatWillRerender />
{expensiveComponentRunsWhenCountChange} #here when ComponentThatWillRerender rerenders, expensiveComponent is recreated, which is not expected as count has not changed
<Count x={count} onClick={()=>setCount(count+1)}/>
)
}