代码之家  ›  专栏  ›  技术社区  ›  Darren

REACT USEFFECT挂钩带警告REACT挂钩/详尽的DEPS

  •  1
  • Darren  · 技术社区  · 5 年前

    我正在转换使用 componentDidMount/Update/Unmount 应对钩子的生命周期 react-hooks/exhaustive-deps 作为警告。

    我们的新代码似乎按预期工作,因此我的想法是关闭这些警告。但是,如果我漏掉了一些东西,下面的代码中是否有警告。

    旧的 组件didmount/update/unmount 代码

      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));
      }
    

    新的react hooks代码

    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 回复  |  直到 5 年前
        1
  •  1
  •   Willman.Codes    5 年前

    在这里,您可以在useffect中使用container,但是由于您也在设置容器状态,因此不能将其作为依赖项,否则您将得到一个无限循环(每次调用setcontainer时,效果都将运行)。

    我想这是个可以接受的时间 // eslint-disable-line

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

    可能还有其他的例子,但是你可以找出哪些useffects需要哪些依赖。