react hooks useEffect() cleanup for only componentWillUnmount?

前端 未结 5 1382
南笙
南笙 2020-12-12 12:32

Let me explain the result of this code for asking my issue easily.

const ForExample = () => {
    const [name, setName] = useState(\'\');
    const [usern         


        
相关标签:
5条回答
  • 2020-12-12 12:54

    Since the cleanup is not dependent on the username, you could put the cleanup in a separate useEffect that is given an empty array as second argument.

    Example

    const { useState, useEffect } = React;
    
    const ForExample = () => {
      const [name, setName] = useState("");
      const [username, setUsername] = useState("");
    
      useEffect(
        () => {
          console.log("effect");
        },
        [username]
      );
    
      useEffect(() => {
        return () => {
          console.log("cleaned up");
        };
      }, []);
    
      const handleName = e => {
        const { value } = e.target;
    
        setName(value);
      };
    
      const handleUsername = e => {
        const { value } = e.target;
    
        setUsername(value);
      };
    
      return (
        <div>
          <div>
            <input value={name} onChange={handleName} />
            <input value={username} onChange={handleUsername} />
          </div>
          <div>
            <div>
              <span>{name}</span>
            </div>
            <div>
              <span>{username}</span>
            </div>
          </div>
        </div>
      );
    };
    
    function App() {
      const [shouldRender, setShouldRender] = useState(true);
    
      useEffect(() => {
        setTimeout(() => {
          setShouldRender(false);
        }, 5000);
      }, []);
    
      return shouldRender ? <ForExample /> : null;
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    0 讨论(0)
  • 2020-12-12 12:58
    function LegoComponent() {
    
      const [lego, setLegos] = React.useState([])
    
      React.useEffect(() => {
        let isSubscribed = true
        fetchLegos().then( legos=> {
          if (isSubscribed) {
            setLegos(legos)
          }
        })
        return () => isSubscribed = false
      }, []);
    
      return (
        <ul>
        {legos.map(lego=> <li>{lego}</li>)}
        </ul>
      )
    }
    

    In the code above, the fetchLegos function returns a promise. We can “cancel” the promise by having a conditional in the scope of useEffect, preventing the app from setting state after the component has unmounted.

    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

    0 讨论(0)
  • 2020-12-12 13:02

    useEffect are isolated within its own scope and gets rendered accordingly. Image from https://reactjs.org/docs/hooks-custom.html

    enter image description here

    0 讨论(0)
  • 2020-12-12 13:04

    instead of creating too many complicated functions and methods what I do is I create an event listener and automatically have mount and unmount done for me without having to worry about doing it manually. Here is an example.

    //componentDidMount
    useEffect( () => {
    
        window.addEventListener("load",  pageLoad);
    
        //component will unmount
        return () => {
           
            window.removeEventListener("load", pageLoad);
        }
    
     });
    

    now that this part is done I just run anything I want from the pageLoad function like this.

    const pageLoad = () =>{
    console.log(I was mounted and unmounted automatically :D)}
    
    0 讨论(0)
  • 2020-12-12 13:13

    you can use more than one useEffect

    for example if my variable is data1 i can use all of this in my component

    useEffect( () => console.log("mount"), [] );
    useEffect( () => console.log("will update data1"), [ data1 ] );
    useEffect( () => console.log("will update any") );
    useEffect( () => () => console.log("will update data1 or unmount"), [ data1 ] );
    useEffect( () => () => console.log("unmount"), [] );
    
    0 讨论(0)
提交回复
热议问题