【问题标题】:Issue when animating modal component with a Portal using React Hooks使用 React Hooks 使用 Portal 为模态组件设置动画时出现问题
【发布时间】:2019-09-14 04:32:15
【问题描述】:

我试图在用户打开和关闭组件时为我的模态组件设置动画。 modal 组件使用 Portal 在页面上挂载和卸载,我正在使用 react-transition-group 库中的 CSSTransitionGroup 为挂载和卸载设置动画。

如果我为 Portal 使用基于类的组件,那么一切都会按预期工作。你可以在这里看到我的完整工作示例:https://codepen.io/jeffcap1/pen/eoQZgp

这是作为类组件的 Portal sn-p:

const portalRoot = document.getElementById("portal");
class Portal extends React.Component {
    constructor(props) {
        super(props);
        this.el = document.createElement("div");
    }

    componentDidMount = () => {
        console.log("Portal componentDidMount!");
        portalRoot.appendChild(this.el);
    };

    componentWillUnmount = () => {
        console.log("Portal componentWillUnmount!");
        portalRoot.removeChild(this.el);
    };

    render() {
        const { children } = this.props;
        return ReactDOM.createPortal(children, this.el);
    }
}

但是,当我尝试更改 Portal 组件以使用新的 React Hooks API,特别是 useEffect 时,内容永远不会添加到页面上。您可以在此处查看完整示例:https://codepen.io/jeffcap1/pen/YMRXxe

Portal sn-p 作为使用 Hooks 的功能组件是:

const portalRoot = document.getElementById("portal");
const Portal = ({ children }) => {
const el = document.createElement("div");

React.useEffect(() => {
        console.log("Portal componentDidMount!");
        portalRoot.appendChild(el);
        return () => {
            console.log("Portal componentWillUnmount!");
            portalRoot.removeChild(el);
        };
    }, []); // eslint-disable-line react-hooks/exhaustive-deps

    return ReactDOM.createPortal(children, el);
};

我很困惑,非常感谢任何关于我做错了什么的见解。

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    嗯,它是这样工作的:

    const {useEffect, useMemo} = React;
    const Portal = ({children}) => {
      const el = useMemo(() => document.createElement("div"), []);
      useEffect(() => {
        portalRoot.appendChild(el);
        return () => {
          portalRoot.removeChild(el);
        }
      }, []);
      return ReactDOM.createPortal(children, el);
    }
    

    笔:https://codepen.io/anon/pen/OGaEbw

    您在每次渲染时都创建 el 而不是一次 - 这可能是问题所在,因为第二次渲染是使用未附加的 el

    【讨论】:

    • 非常感谢,这么简单的修复!您如何能够调试 el 被创建太多次并覆盖自身,或者这是您从经验中学到的东西?
    • @jeffcap1 函数体中的所有内容在每次渲染时都会被调用,但函数内部可以有记忆(如useMemouseCallbackuseEffect 做)所以它不会那么痛苦并且可以保留引用随着时间的推移 - 这就是为什么钩子是一回事。
    • 你是英雄伴侣
    猜你喜欢
    • 2021-11-19
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多