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
useEffect
runs
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)
useLayoutEffect
runs, 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