3

I am converting code that used componentDidMount/Update/Unmount lifecycle to React Hooks and keep coming up against react-hooks/exhaustive-deps in the console as a warning.

Our new code appears to work as intended and so my thoughts are to turn these warnings off. However, in case I have missed something, are the warnings warranted in the below code.

Old componentDidMount/Update/Unmount code

  state = {
    container: canUseDOM ? createContainer(this.props.zIndex) : undefined,
    portalIsMounted: false,
  };

  componentDidUpdate(prevProps: Props, prevState: State) {
    const { container } = this.state;
    const { zIndex } = this.props;
    if (container && prevProps.zIndex !== zIndex) {
      const newContainer = createContainer(zIndex);

      getPortalParent().replaceChild(container, newContainer);
      this.setState({ container: newContainer });
    } else if (!prevState.container && container) {
      getPortalParent().appendChild(container);
    }
  }

  componentDidMount() {
    const { container } = this.state;
    const { zIndex } = this.props;
    if (container) {
      getPortalParent().appendChild(container);
    } else {
      const newContainer = createContainer(zIndex);
      this.setState({ container: newContainer });
    }
    this.setState({
      portalIsMounted: true,
    });

    firePortalEvent(PORTAL_MOUNT_EVENT, Number(zIndex));
  }

  componentWillUnmount() {
    const { container } = this.state;
    const { zIndex } = this.props;
    if (container) {
      getPortalParent().removeChild(container);
      const portals = !!document.querySelector(
        'body > .portal-container > .portal',
      );
      if (!portals) {
        getBody().removeChild(getPortalParent());
      }
    }

    firePortalEvent(PORTAL_UNMOUNT_EVENT, Number(zIndex));
  }

New React Hooks code

const [container, setContainer] = useState(canUseDOM ? createContainer(zIndex) : undefined);
const [portalIsMounted, setPortalIsMounted] = useState(false);

  useEffect(() => {
    if (container) {
      const newContainer = createContainer(zIndex);
      getPortalParent().replaceWith(container, newContainer);
      setContainer(newContainer);
    }
  }, [zIndex]);

  useEffect(() => {
    if (container) {
      getPortalParent().appendChild(container);
    }
  }, [container]);

  useEffect(() => {
    if (container) {
      getPortalParent().appendChild(container);
    } else {
      const newContainer = createContainer(zIndex);
      setContainer(newContainer);
    }
    setPortalIsMounted(true);
    firePortalEvent(PORTAL_MOUNT_EVENT, Number(zIndex));
  }, []);

  useEffect(() => {
    if (container) {
      getPortalParent().removeChild(container);
      const portals = !!document.querySelector(
        'body > .portal-container > .portal'
      );
      if (!portals) {
        getBody().removeChild(getPortalParent());
      }
    }

    firePortalEvent(PORTAL_UNMOUNT_EVENT, Number(zIndex));
  }, []);
1
  • 1
    code for componentWillUnmount should be returned from useEffect callback Commented Oct 24, 2019 at 22:29

1 Answer 1

3

Here you use container in your useEffect, however since you are also setting container state in this effect you cannot put it as a dependency or else you will get an infinite loop (the effect will run every time setContainer is called).

I think this may be an acceptable time to use // eslint-disable-line

useEffect(() => {       
   if (container) {
      const newContainer = createContainer(zIndex);
      getPortalParent().replaceWith(container, newContainer);
      setContainer(newContainer);
   }
// eslint-disable-line
}, [zIndex]);

There may be other examples but you can figure out which useEffects require what dependancies.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.