HeathenINedeN
HeathenINedeN

Reputation: 123

How do I convert componentDidMount() and componentWillUnmount to the useEffect()?

I am trying to create a popup window that notifies the user to press save progress if they navigate away. I need to convert the following code into hooks:

class Prompt extends React.Component {
  componentDidMount() {
    window.addEventListener('beforeunload', this.beforeunload.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener('beforeunload', this.beforeunload.bind(this));
  }

  beforeunload(e) {
    if (this.props.dataUnsaved) {
      e.preventDefault();
      e.returnValue = true;
    }
  }

  render() {...}
}

I know that I am supposed to use useEffect() but not sure how as I am unfamiliar with hooks in general. In particular I'm not sure what to put as the second argument, since the hooks don't like this.bind. Any help would be greatly appreciated.

Upvotes: 1

Views: 477

Answers (4)

Shahnawaz Hossan
Shahnawaz Hossan

Reputation: 2720

You can use hooks for your above code in this way:

function App(props) {

  useEffect(() => {

    window.addEventListener('beforeunload', beforeunload);

    // returned function will be called on component unmount 
    return () => {
      window.removeEventListener('beforeunload', beforeunload);
    }
  }, []);

  const beforeunload = (e) => {
    if (props.dataUnsaved) {
      e.preventDefault();
      e.returnValue = true;
    }
  };

  return (
    <div>Hello World</div>
  );
}

Note: Without using the second parameter(here is empty), your hook will be called on every render of the component. So be careful about that.

Upvotes: 1

Nat&#225;lia Zanolli
Nat&#225;lia Zanolli

Reputation: 314

I think is something like this, I didn't test, but in this code the useEffect will run when mount and when the prop "dataUnsaved" has any change, and the return statement will run in the ummount component, read more in React docs about cleanup fuction.

function Prompt({dataUnsaved}) {
  useEffect(() => {
    const beforeunload = (e) => {
      e.preventDefault();
      e.returnValue = true;
    }

    window.addEventListener("beforeunload", beforeunload);

    return () => {
      window.removeEventListener("beforeunload", beforeunload);
    }
  }, [dataUnsaved]);

  return <div />
}

Upvotes: 1

asmaa
asmaa

Reputation: 725

According to React Docs:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

so componentDidMount will be:

useEffect(() => { // yourCode },[])

and since componentWillUnmout is used for cleanup See React Docs you can use it in return like this one:

useEffect(() => {
  window.addEventListener('beforeunload', () => {});

  return () => {
    window.removeEventListener('beforeunload', () => {})
  }
}, [])

Upvotes: 2

Til
Til

Reputation: 19

you can use useEffect like this:

useEffect(() => {
// like componentDidMount
 return function cleanup() {
    // like componentWillUnmount
  };
}, [exampleProp]);

useEffect will only be triggered if one of the props in the second argument have changed. If you do not pass a second argument useEffect act like componentDidUpdate. For further information visit: https://reactjs.org/docs/hooks-effect.html

Upvotes: 1

Related Questions