React Hooks - Part 2


Content
- Context API
- Additional Hooks

> Init



> Case of study

+ Step = branch
Context API
> Props vs Store


Props vs Store
Props Drilling !!!!
Context API
> Store


State
Action


New State
State + Action = Merge past state and modify just with the new action
Context API
> Characteristics

- Not need pass props through every level of the tree: Share global data.
- Out the box: Built on the top of react.
- Easy to use with hooks.
Context API
> Characteristics
- Create Context.
- Context.provider.
- useContext hook
import React, { createContext, useReducer } from "react";
import { fetchCatsActions, deleteCatAction, addCatAction } from "./AppActions";
import AppReducer from "./AppReducer";
// Initial State
const initialState = {
cats: []
};
// Create context
export const GlobalContext = createContext(initialState);
// Provider component
export const GlobalProvider = ({ children }) => {
...
return (
<GlobalContext.Provider
value={{
cats: state.cats,
...catActions
}}
>
{children}
</GlobalContext.Provider>
);
};

export default function useGetCatsData (requestId, catNumber) {
const { cats, fetchCats } = useContext(GlobalContext);
useEffect(() => {
getCat();
}, [requestId]);
async function getCat () {
const data = await catRequest(catNumber);
fetchCats(data);
}
useDebugValue(cats.length === 0 ? 'Empty cat data' : 'Already fetched cat data');
return cats;
}Context API
> Actions

export const addCatAction = dispatch => cat => {
return dispatch({
type: ADD_CAT,
payload: cat
});
};
export default reducer (state, action) => {
switch (action.type) {
....
case ADD_CAT:
return {
...state,
cats: [action.payload, ...state.cats]
};
default:
return state;
}
};
Use Reducer
const [state, dispatch] =
useReducer(AppReducer, initialState);
const fetchCats = fetchCatsActions(dispatch);
const deleteCat = deleteCatAction(dispatch);
const addCat = addCatAction(dispatch);
const catActions = {
fetchCats,
deleteCat,
addCat
};
return (
<GlobalContext.Provider
value={{
cats: state.cats,
...catActions
}}
>
.....Context API
> Actions

function CatList() {
const { addCat } = useContext(GlobalContext);
const addCatOnClick = async (ev) => {
const data = await catRequest(1);
addCat(data[0]);
}
...Extra hooks
> Actions

- useCallback
- useMemo
- useRef
- useLayoutEffect
- useDebugValue
useCallback
> Additional Hooks

function CatList({numberOfCats}) {
const [catData, setCatData] = useState([]);
async function fetchCats () {
const data = await catRequest(numberOfCats);
setCatData(data);
}
// fetch more cats
const onClick = (ev) => {
fetchCats();
}
useEffect(() => {
fetchCats();
}, []);
....
React Hook useEffect has a missing dependency: 'fetchCats'. Either include it or remove the dependency array react-hooks/exhaustive-deps
useCallback
> Additional Hooks


function CatList({numberOfCats}) {
const [catData, setCatData] = useState([]);
const fetchCats = useCallback(async () => {
const data = await catRequest(numberOfCats);
setCatData(data);
}, [numberOfCats]);
// fetch more cats
const onClick = (ev) => {
fetchCats();
}
useEffect(() => {
fetchCats();
}, [fetchCats]);Returns a memoized callback.
useMemo
> Additional Hooks

import React, { useEffect } from 'react';
let renderCount = 0;
export default function CatTail() {
useEffect(() => {
renderCount ++;
});
return (
<div>
<h3>Render tail count = {renderCount}</h3>
</div>
)
}
function CatList() {
...
return (
....
<CatTail />
...
);
}
export default CatList;
useMemo
> Additional Hooks

Returns a memoized value.
...
function CatList() {
...
const memoElement = useMemo(() => {
return <CatTail />;
}, [catData.length]);
return (
<div className="list">
...
{memoElement}
</div>
);
}
export default CatList;
useLayoutEffect & Use Ref
> Additional Hooks

....
const listRef = useRef(null);
...
useLayoutEffect(() => {
if (listRef.current.clientHeight > 600) {
listRef.current.style.border = `2px solid #9c88ff`;
} else {
listRef.current.style.border = '';
}
});
return (
<div className="list" ref={listRef}>
...
</div>
);
}
useDebugValue
> Additional Hooks

}
useDebugValue(cats.length === 0 ? 'Empty cat data' : 'Already fetched cat data');
return cats;
Conclusions
> Reuse everywhere!
- Context API: easy context sharing.
- Store + useReducer + useContext
- Performance: useMemo - useCallback.
- Layout and render sync: useLayout & useRef
- UsedebugValue

Gracias!

Ben Awad: https://www.youtube.com/watch?v=ommC6fS1SZg
https://medium.com/@jan.hesters/usecallback-vs-usememo-c23ad1dc60
Reack hooks part 2
By Daniel Diaz Giraldo
Reack hooks part 2
- 219