RulerNature
RulerNature

Reputation: 753

React class old lifeCycle methods into hooks

I need to rewrite this old lifeCycle methods with useEffect hook and I am not sure how.

componentDidMount() {
    document.addEventListener("mousedown", this.handleClickOutside);
    this.setState({
      defaultSelectText: this.props.defaultText
    });
  }

  componentWillUnmount() {
    document.removeEventListener("mousedown", this.handleClickOutside);
  }

I have tried in this way but didn't really worked:

useEffect((props) => {
    document.addEventListener("mousedown", this.handleClickOutside);
    defaultSelectText(props.defaultText)

 }, []);

Reproducible Example: https://codesandbox.io/s/weathered-sun-ej9tp?file=/src/DropDownSelect.js

Upvotes: 2

Views: 62

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074258

There are two parts to that:

  1. Adding and removing the event listener
  2. Converting props to state on mount

1. Adding and removing the event listener

You're right to use useEffect, but useEffect doesn't pass any argument to its callback. To remove the listener, you return a cleanup function:

useEffect(() => {
    const handler = handleClickOutside;
    document.addEventListener("mousedown", handler);
    return () => {
        document.removeEventListener("mousedown", handler);
    };
}, []);

Notice that we capture the function we set in handler so that we could be sure to remove the same function (in case handleClickOutside gets recreated, as function sometimes do in function components).

2. Converting props to state on mount

Don't. :-) Props are state that your parent component manages. Your component shouldn't copy props to state, 99.9% of the time it's an anti-pattern; instead, it should just use the props. If the component needs to be able to change the value of a prop, the parent component should pass it a function to do that. See the documentation for the class component getDerivedStateFromProps function for more about not doing this.

In your case, you were only copying the prop to state on mount, which means that updates to the prop after mount were not being used. In the very rare use case where you need to do that, the equivalent with hooks is to use the prop as the initial value with useState:

function Example({defaultText}) {
    const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
    // ...
}

And for completeness, for the very rare use case where you need to have a state property that's updated whenever a prop is updated, you'd use useEffect:

function Example({defaultText}) {
    const [defaultSelectText, setDefaultSelectText] = useState(defaultText);
    // ...
    useEffect(() => {
        setDefaultSelectText(defaultText);
    }, [defaultText]); // <== Dependency is the prop
    // ...
}

...but note that that particular example is pointless; the state value just mirrors the prop. You'd have to be doing something with the value when making it state for that to make sense.

Upvotes: 1

Rashed Rahat
Rashed Rahat

Reputation: 2475

Here is the code:

useEffect(() => {
    const handler = handleClickOutside;
    document.addEventListener("mousedown", handler); // Will be executed when component did mount
    defaultSelectText(props.defaultText); // Will be executed when component did mount

    return () => document.removeEventListener("mousedown", handler); // Will be executed when component will unmounted
 }, []);

Happy coding :)

Upvotes: 1

Ravi Chaudhary
Ravi Chaudhary

Reputation: 670

You are almost there. For componentDidMount you pass empty array as dependencies which means, callback function passed to useEffect would be invoked only once i.e. after component is rendered/mounted the first time. For componentWillUnmount , you return the function that you would like to be called as part of unmount operation.

useEffect((props) => {
    document.addEventListener("mousedown", this.handleClickOutside);
    defaultSelectText(props.defaultText);

    return () => document.removeEventListener("mousedown", this.handleClickOutside);

 }, []);

Upvotes: 1

Related Questions