> Init
> Case of study
+ Step = branch
> Props vs Store
Props vs Store
Props Drilling !!!!
> Store
State
Action
New State
State + Action = Merge past state and modify just with the new action
> Characteristics
> Characteristics
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;
}> 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
}}
>
.....> Actions
function CatList() {
const { addCat } = useContext(GlobalContext);
const addCatOnClick = async (ev) => {
const data = await catRequest(1);
addCat(data[0]);
}
...> Actions
> 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
> 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.
> 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;> Additional Hooks
Returns a memoized value.
...
function CatList() {
...
const memoElement = useMemo(() => {
return <CatTail />;
}, [catData.length]);
return (
<div className="list">
...
{memoElement}
</div>
);
}
export default CatList;> 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>
);
}> Additional Hooks
}
useDebugValue(cats.length === 0 ? 'Empty cat data' : 'Already fetched cat data');
return cats;> Reuse everywhere!
Ben Awad: https://www.youtube.com/watch?v=ommC6fS1SZg
https://medium.com/@jan.hesters/usecallback-vs-usememo-c23ad1dc60