React ~ Hooks ~ useEffect - rohit120582sharma/Documentation GitHub Wiki

A side effect is anything that interacts with the outside world. Mutating non-local variables, making network requests, and updating the DOM are all examples of common side effects.

The useEffect allows you to perform side effects in function components. It is a close replacement for componentDidMount, componentDidUpdate, and componentWillUnmount, but unified into a single API.

But if you want to manipulate DOM in the effect, and want to make sure it happens before browser paint, you need to use useLayoutEffect. The syntax is the same as useEffect.

There are three aspects to the useEffect API that are important to understand: - how to add an effect, how to skip re-invoking the effect, and how to (optionally) clean up that effect.

  • Add an effect

    To add a side effect to your React component, you invoke useEffect passing it a function only which defines your side effect. This callback function will be fired after every render (browser layout and paint).

    React.useEffect(() => {
        document.title = 'The new title.'
    })
  • Skipping re-invoking an effect

    If you pass a second argument to useEffect, you need to pass to it an array of all of the outside values your effect depends on. This typically leads us to one of three scenarios - no second argument, an array of all outside values the effect depends on, or an empty array (assuming your effect doesn’t depend on any values).

    React.useEffect(() => {
        // Will be invoked on the initial render and all subsequent re-renders
    });
    
    React.useEffect(() => {
        // Will be invoked on the initial render and when "id" / "authed" changes
        // Similar to componentDidUpdate
    }, [id, authed]);
    
    React.useEffect(() => {
        // Will only be invoked on the initial render
        // Similar to componentDidMount
    }, []);
  • Cleaning up an effect (optional)

    If you return a function from useEffect, React will make sure that function is invoked right before the component is removed from the DOM. Additionally, if your component is re-rendered, the cleanup function for the previous render’s effect will be invoked before re-invoking the new effect.

    React.useEffect(() => {
        ...
        return () => {
            // clean up tasks
        }
    })

Example

function TrackMouse() {
    // Add mousemove event on componentDidMount and remove event on componentWillUnmount
    const [x, setX] = React.useState(0);
    const [y, setY] = React.useState(0);

    React.useEffect(() => {
        const logMousePosition = (e) => {
            setX(e.clientX);
            setY(e.clientY);
        }
        window.addEventListener('mousemove', logMousePosition);

        return () => window.removeEventListener('mousemove', logMousePosition);
    }, []);
    return (
        <div>
            <p>Mouse position is: x:{x} & y:{y}</p>
        </div>
    );
}
function ShowPosts() {
    // Load posts on componentDidMount and load a specific post whenever postId changed
    const [posts, setPosts] = React.useState([]);
    const [postId, setPostId] = React.useState(1);

    React.useEffect(() => {
        axios.get('https://jsonplaceholder.typicode.com/posts')
            .then(res => setPosts(res.data))
            .catch(console.error);
    }, []);
    React.useEffect(() => {
        axios.get('https://jsonplaceholder.typicode.com/posts/${postId}')
            .then(res => console.log('Post =', res.data))
            .catch(console.error);
    }, [postId]);

    return (
        <div>
            <ul>
                {posts.map(post => <li key={post.id} onClick={() => setPostId(post.id)}>{post.title}</li>)}
            </ul>
        </div>
    );
}
⚠️ **GitHub.com Fallback** ⚠️