# React Hooks Tips
# Example codebase
Please find my personal react hooks practices here.
# useMemo vs useCallback
`useMemo`: returns the value of that callback function
`useCallback`: returns the callback function
# useContext
Usage: share state values between components
- Example:
// Step 1: Define a context:
import { createContext } from 'react';
export default createContext(null);
// Step 2: set context provider value:
import UserContext from '../src/context/UserContext';
<UserContext.Provider value={{ userData, setUserData }}>
...
</UserContext.Provider>
// complete example:
import UserContext from '../src/context/UserContext';
export default function App() {
const [userData, setUserData] = useState({
token: undefined,
user: undefined,
});
useEffect(() => {
const checkLoggedIn = async () => {
let token = localStorage.getItem('auth-token');
if (token === null) {
localStorage.setItem('auth-token', '');
token = '';
}
try {
const tokenResponse = await axios.post('http://localhost:6285/user/tokenIsValid', null, {
headers: {
"x-auth-token": token
}
});
if (tokenResponse.data) {
const getCurrentUser = await axios.get('http://localhost:6285/user', {
headers: {
"x-auth-token": token
}
});
if (getCurrentUser) {
setUserData({
token,
user: getCurrentUser.data
});
}
}
} catch (error) {
console.log("error: ", error.message);
}
};
checkLoggedIn();
}, []);
return (
<BrowserRouter>
<UserContext.Provider value={{ userData, setUserData }}>
<Header />
<div className="container">
<Switch>
<Route path="/" component={Home} exact />
<Route path="/login" component={Login} exact />
<Route path="/register" component={Register} exact />
<Route path="*" component={NotFound} />
</Switch>
</div>
</UserContext.Provider>
</BrowserRouter>
)
}
// Step 3: use context value in components:
import UseContext from '../context/UserContext';
const { userData: { user } } = useContext(UseContext);
// complete example:
export default function Home() {
const [preLoader, setPreLoader] = useState(false);
const { userData: { user } } = useContext(UseContext);
const history = useHistory();
useEffect(() => {
setPreLoader(true);
if (!user) {
setPreLoader(false);
history.push('/login');
}
setPreLoader(false);
}, [history, user]);
return preLoader ? (<p>Loading ..</p>) : (
<div className="page">
Home
</div>
)
}
// Find details on codebase: mern-jwt-trial-front-end
# useReducer
- TBD
# Another useMemo/memo, useCallback example
Normally we try to avoid unnecessary re-render, we use memo or useMemo, and we parent passes array or object (reference type of data)
to child, we need to use useMemo to avoid the re-render issue !!
When we pass function to child, we use useCallback for it
Code example of using useMemo:
// Find code from: https://github.com/DamengRandom/hooks-recall/blob/master/src/components/useMemoUseCallbackThirdExample/TheParent.jsx#L12
// parent component:
const arrayReference = React.useMemo(() => [1, 2, 3], []);
// child component:
<SecondChild arrayReference={arrayReference} />
Code example of using useCallback:
// parent component
const fetcher = React.useCallback((type) => {
return fetch(`https://jsonplaceholder.typicode.com/${type}/1`)
.then(response => response.json())
.then(json => console.log(json));
}, []);
React.useEffect(() => {
fetcher('todos');
}, [fetcher]);
// child component:
<ThirdChild fetcher={fetcher} />
Last point: when every time we saw the dependencies comes from parent level, we may need to consider whether shall we use related useMemo/memo or useCallback hooks to enhance the performance