Class vs Hooks
- componentDidMount
useEffect(() => {
// Your code here
}, []);
- componentDidUpdate
useEffect(() => {
// Your code here
}, [yourDependency]);
- componentWillUnmount
useEffect(() => {
// componentWillUnmount
return () => {
// Your code here
}
}, [yourDependency]);
What is life cycle of useEffect?
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
function LifecycleDemo() {
// It takes a function
useEffect(() => {
// This gets called after every render, by default
// (the first one, and every one after that)
console.log('render!');
// If you want to implement componentWillUnmount,
// return a function from here, and React will call
// it prior to unmounting.
return () => console.log('unmounting...');
}, [ // dependencies to watch = leave blank to run once or you will get a stack overflow ]);
return "I'm a lifecycle demo";
}
function App() {
// Set up a piece of state, just so that we have
// a way to trigger a re-render.
const [random, setRandom] = useState(Math.random());
// Set up another piece of state to keep track of
// whether the LifecycleDemo is shown or hidden
const [mounted, setMounted] = useState(true);
// This function will change the random number,
// and trigger a re-render (in the console,
// you'll see a "render!" from LifecycleDemo)
const reRender = () => setRandom(Math.random());
// This function will unmount and re-mount the
// LifecycleDemo, so you can see its cleanup function
// being called.
const toggle = () => setMounted(!mounted);
return (
<>
<button onClick={reRender}>Re-render</button>
<button onClick={toggle}>Show/Hide LifecycleDemo</button>
{mounted && <LifecycleDemo/>}
</>
);
}
ReactDOM.render(<App/>, document.querySelector('#root'));
What are differences between useEffect and useLayoutEffect?
useEffect
useEffect runs asynchronously and after a render is painted to the screen.
- You cause a render somehow (change state, or the parent re-renders)
- React renders your component (calls it)
- The screen is visually updated
- THEN
useEffectruns
useLayoutEffect
useLayoutEffect, on the other hand, runs synchronously after a render but before the screen is updated. That goes:
- You cause a render somehow (change state, or the parent re-renders)
- React renders your component (calls it)
useLayoutEffectruns, and React waits for it to finish.- The screen is visually updated
When to use useEffect?
- Fetching data is not going to result in an immediate change
- Setting up an event handler
- Resetting some state when a modal dialog appears or disappears
When to use useLayoutEffect?
If your component is flickering when state is updated because it renders in a partially-ready state first and then immediately re-renders in its final state.
import React, {
useState,
useLayoutEffect
} from 'react';
import ReactDOM from 'react-dom';
const BlinkyRender = () => {
const [value, setValue] = useState(0);
useLayoutEffect(() => {
if (value === 0) {
setValue(10 + Math.random() * 200);
}
}, [value]);
console.log('render', value);
return (
<div onClick={() => setValue(0)}>
value: {value}
</div>
);
};
ReactDOM.render(
<BlinkyRender />,
document.querySelector('#root')
);
useLayoutEffect only updates visually once even though the component rendered twice.
The useEffect version, on the other hand, visually renders twice, so you see a flicker where the value is briefly 0.
How to use “useReducer”?
reducer.js
export const initialState = {
employeeDetail: null,
photo: ''
}
export const reducer = (state, action) => {
switch (action.type) {
case 'SELECT_EMPLOYEE':
return {
...state,
employeeDetail: action.employeeDetail
}
case 'SET_PHOTO':
return {
...state,
photo: action.photo
}
default:
return state
}
}
actions.js
export const setEmployeeDetail = (dispatch, employeeDetail) => {
dispatch({
type: 'SELECT_EMPLOYEE',
employeeDetail: employeeDetail
})
}
export const setPhoto = (dispatch, photo) => {
dispatch({
type: 'SET_PHOTO',
photo: photo
})
}
react-component.js
import React, {useEffect, useReducer} from 'react'
...
const TemperatureForm = () => {
const [state, dispatch] = useReducer(reducer, initialState)
useEffect(() => {
// Fetch data
const employeeDetail ={...}
setEmployeeDetail(dispatch, employeeDetail)
}
return <>
<Text>{state.employeeDetail.name}</Text>
</>
}
Leave a Reply