Проблема при анимации модального компонента с помощью портала с использованием React Hooks - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь анимировать мой модальный компонент, когда пользователь открывает и закрывает компонент. Модальный компонент использует Portal для монтирования и размонтирования на странице, а я использую CSSTransitionGroup из библиотекиact-transition-group для анимации монтирования и размонтирования.

Если я использую основанный на классах компонент для портала, все работает как положено. Вы можете увидеть мой полный рабочий пример здесь: https://codepen.io/jeffcap1/pen/eoQZgp

Вот фрагмент портала как компонент класса:

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 для использования нового API React Hooks, в частности useEffect, содержимое никогда не добавляется на страницу. Вы можете увидеть полный пример здесь: https://codepen.io/jeffcap1/pen/YMRXxe

Фрагмент портала как функциональный компонент с использованием хуков:

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

Я довольно озадачен и был бы очень признателен за понимание того, что я делаю неправильно, очень хотелось бы.

1 Ответ

1 голос
/ 25 апреля 2019

Ну, это работает так:

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

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

Вы создавали el каждый рендер вместо одного - это может быть проблемой, потому что второйрендер был с el, который не добавлен.

...