Есть ли способ выполнить функцию очистки перед новым рендерингом на функциональном компоненте? - PullRequest
0 голосов
/ 25 сентября 2019

Описание

У меня есть SomeComponent , который использует некоторую библиотеку (мы назовем domLib ), котораяизменяет DOM напрямую (например, изменяет и добавляет несколько элементов и слушателей). SomeComponent также принимает реквизиты данные , которые domlib использует

const SomeComponent = ({ data }) => {
    useEffect(() => {
        domLib.init(data, 'example-container');
        return () => { //cleanup function
            domLib.destroy('example-container'); //removes everything from example-container, listeners etc from example-container
        }
    },[data])
    return (<div id='example-container'>
        <HelpComponent data={data}/>
    </div>)
}

domLib также должен иметь возможность видеть / изменять HelpComponent или дочерние элементы ' example-container '

  • SomeComponent принимает реквизиты, данные
  • Ребенок SomeComponent с именем HelpComponent использует данные реквизита
  • Библиотека domLib использует и данные и HelpComponent для изменения DOM (дочерних элементов ' example-container ')

Проблема

При получении новых реквизитов / обновлений, поскольку функция очистки запускает ПОСЛЕ рендеринга, domLib.destroy('example-container'); удаляет дочерние элементы Пример-контейнер , что означает, что <HelpComponent data={data}/> также будет удалено

Попытки и проблемыues

useEffect(() => {
    domLib.destroy('example-container');
    ReactDom.unmountComponentAtNode(document.getElementById('example-container'))
    ReactDom.render(<HelpComponent data={data}/>, document.getElementById('example-container'))
    domLib.init(data, 'example-container');
})
return (<div id='example-container'>
    {/* removed */}
</div>)

Попытка , создайте все внутри хука useEffect , используя ReactDom , и удалите все, что мне нужно, прямо перед ним.

Выпуск , метод рендеринга в ReactDom.render(<HelpComponent data={data}/>, document.getElementById('example-container')) не сразу применяет изменения к DOM, поэтому, когда domLib не может видеть HelpComponent

Редактировать для большей ясности

Библиотека domLib jsPlumb , которую я использую для создания связей междуэлементы.Элементы создаются на основе данных, а lib jsPlumb создает связи между этими элементами.

Проблема в том, что элементы, созданные из jsPlumb, находятся за пределами реагирующей экосистемы, поэтому она остается между обновлениями, поэтому мне нужно удалить их между обновлениями

1 Ответ

0 голосов
/ 25 сентября 2019

Добавьте [] в качестве второго аргумента для useEffect, чтобы он запускался один раз.Если вам нужны какие-либо реквизиты для вашей библиотеки, добавьте их, чтобы следить за изменениями.Ваш крюк будет работать только тогда.Для более полезной информации, написанной Дэном: https://overreacted.io/a-complete-guide-to-useeffect/ или документами: https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect

РЕДАКТИРОВАТЬ: для просмотра изменений некоторых реквизитов добавьте их в квадратные скобки в useEffect.Пример из документации:

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

Если вы хотите вызвать метод уничтожения только один раз, независимо от изменений данных, сделайте следующее:

useEffect(
  () => {
    return () => {
      subscription.unsubscribe();
    };
  },
  [],
);

Пустое тело функции ничего не изменит напри первом запуске, но возвращаемая функция запускается при разрушении.

...