Как размонтировать компонент react
Перейти к содержимому

Как размонтировать компонент react

  • автор:

Как безопасно размонтировать компонент в React?

Получаю ошибку:
Failed to execute ‘removeChild’ on ‘Node’: The node to be removed is not a child of this node.

  • Вопрос задан более трёх лет назад
  • 348 просмотров

4 комментария

Средний 4 комментария

Еще не видел такого.
Чем вам условный рендеринг не подошел?
Артем @Cruper Автор вопроса

Medin K, какой условный рендеринг?
Проблема в том, что источник события, из-за которого меняется условие рендерить компонент или нет, находится не в том компоненте, в котором находится компонент.
Если вынести кнопку из componentC в componentA, то работать будет
UPD. Пример не совсем правильный
Должно быть так:

// componentA.jsx class ComponentA extends React.PureComponent < removeB() < this.setState(< mounted: false >) > renderB() < if (!this.state.mounted) < return null >return > render() < return 
/>
> > // componentB.jsx class ComponentB extends React.PureComponent < render() < return // Какой-то контент >>

Как правильно сделать размонтирование элемента (блока) в react.js?

В документации сказано, что componentWillUnmount запускается перед размонтирование элемента из DOM. Но как сделать размонтирование элента?
Говоря попросту мне надо один элемент заменить другим, которые привязаны к одному id или просто удалить элемент.
Как грамотно это сделать, что бы запускался componentWillUnmount у элемента, который удаляется из DOM?

  • Вопрос задан более трёх лет назад
  • 5301 просмотр

3 комментария

Оценить 3 комментария

Laiff

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

LB777

LB777 @LB777 Автор вопроса

Андрей Антропов: Мне как раз надо отписаться от слушателя. И как я понял, что componentWillUnmount сработает когда объект, скажем var FluxCart = React.createClass(<. >), будет размонтирован из DOM. Соответственно вопрос заключается в том как размонтировать (удалить) из DOM.

Сделать так что бы компонент не монтировался. Или тут что то супер сложное есть ? При каждом сетСтейте реакт обновляет все дерево компонентов ниже. Сделать сет стейт, передать пропс который укажет на то что бы мы не рендерели компонент

Как сделать componentWillUnmount в хуках

При использовании react portal создает див, куда кладется компонент, но при исчезновении(on Unmount), в DOM остается пустой див. Не красивенько, как исправить?

import < useEffect, useMemo >from 'react'; import <> from './styles'; import < createPortal >from 'react-dom'; const CollectionPreviewItem = ( < component >) => < const el = useMemo(()=>document.createElement ( 'div' ),[]); useEffect ( () => < document.body.appendChild ( el ); >, [ el ] ); return ( createPortal ( component, el ) ); >; export default CollectionPreviewItem;

Отслеживать
задан 1 апр 2020 в 21:21
Светлана Свиридова Светлана Свиридова
192 10 10 бронзовых знаков
Хук useEffect должен возвратить функцию, которая и будет вызываться при исчезновении элемента
1 апр 2020 в 21:38
return *; — то, что вам нужно (в useEffect)
1 апр 2020 в 21:40
@Denis Bubnov помогите пожалуйста ru.stackoverflow.com/questions/1109017/…
12 апр 2020 в 6:51

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Хук useEffect представляет собой совокупность методов жизненного цикла React, таких как componentDidMount , componentDidUpdate , и componentWillUnmount .

Если вы хотите запустить эффект и сбросить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ( [] ) вторым аргументом. React посчитает, что ваш эффект не зависит от каких-либо значений из пропсов или состояния и поэтому не будет выполнять повторных запусков эффекта. Это не обрабатывается как особый случай — он напрямую следует из логики работы входных массивов.

Условное срабатывание эффекта: по-умолчанию эффекты запускаются после каждого завершённого рендера. Таким образом, эффект всегда пересоздаётся, если значение какой-то из зависимости изменилось. Однако в некоторых случаях это может быть излишним, чтобы реализовать это (не выполнять эффект каждый раз), передайте второй аргумент в useEffect , который является массивом значений, от которых зависит эффект.

Вот тут мы и подобрались к самому интересному — очистка эффекта. Часто эффекты создают ресурсы, которые необходимо очистить (или сбросить) перед тем, как компонент покидает экран, например подписку или идентификатор таймера. Чтобы сделать это, функция переданная в useEffect , может вернуть функцию очистки. То есть, если из хука useEffect вернуть функцию — она будет вызвана во время размонтирования ( componentWillUnmount ), вот так:

useEffect(() => < document.body.appendChild(el); return () =>< // Делайте в этом блоке что нужно, это и есть `componentWillUnmount` >; >, [el]); 

Функция очистки запускается до удаления компонента из пользовательского интерфейса, чтобы предотвратить утечки памяти. Кроме того, если компонент рендерится несколько раз (как обычно происходит), предыдущий эффект очищается перед выполнением следующего эффекта.

Также рекомендую ознакомиться с порядком срабатывания эффектов. В отличие от componentDidMount и componentDidUpdate , функция, переданная в useEffect , запускается во время отложенного события после разметки и отрисовки.

Изменение DOM, которое видно пользователю, должно запускаться синхронно до следующей отрисовки, чтобы пользователь не замечал визуального несоответствия. Для этих типов эффектов React предоставляет один дополнительный хук, называемый useLayoutEffect . Советую обратить ваше внимание на этот хук.

Почему не размонтируется компонент?

Author24 — интернет-сервис помощи студентам

В этом случае, всё работает как надо: Каждый раз при включении и выключении conditionToShow, у Component1 вызываются соответственно обработчики componentDidMount() и componentWillUnmount().

Потом (т.к. хочу чтобы Component1 стал контентом модального окна) меняю на (из Ant Design).

1 2 3 4 5 6
render() { return ( Modal visible={this.props.conditionToShow} > {this.props.conditionToShow && Component1 />} Modal> )

В этом случае Component1 монтируется только единожды, при первом включении conditionToShow. Далее при выключении условия размонтирования компонента не происходит, и соответственно компонент уже не монтируется заново, при повторном включении.

Почему рендеринг компонента завернутого в и в происходит по разному?
Что надо сделать чтобы во втором случае тоже происходило размонтирование?

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Почему не даёт использовать компонент ReportViewer?
Здравствуйте!Такая проблема!Создал БД через DataGrid и затем хотел добавить ReportViewer,полез в.

Почему компонент не изменяет размеры (создание компонента)
constructor TBlt.Create(AOwner: TComponent); begin inherited Create(AOwner); Parent :=.

Почему Yii компонент multimodelform ничего не выводит?
Добрый день, не отображется вывод мультимодельной формы: Сделал все по мануалу для.

Почему не работает компонент TreeView в Windows Forms
Нужно написать дерево состоящее по буквам заданных слов. Нашел похоже, попытался переделать, но не.

603 / 403 / 212
Регистрация: 30.04.2017
Сообщений: 743

ЦитатаСообщение от winch Посмотреть сообщение

Почему рендеринг компонента завернутого в

и в происходит по разному?

ЦитатаСообщение от winch Посмотреть сообщение

(из Ant Design).

Modal сразу монтируется вместе со скрытым контентом в html дерево и при переключении свойства visible оно лишь меняет css свойство на отображение -скрытие. Такое монтирование позволяет при скрытии сделать плавный эффект перехода.

ЦитатаСообщение от winch Посмотреть сообщение

Что надо сделать чтобы во втором случае тоже происходило размонтирование?

Варианты зависят от задачи:
— ну можно повесить такое же условие для монтирование на Modal — но тогда, пропадет эффект плавности,
если повесить условие на внутренний компонент, то содержимое перед скрытием будет скакать.
(некрасивое решение)
— написать логику для размонтирования спустя секунду после отработки эффекта, и для монтирования без задержки (костыльное решение)
— переписать логику componentDidMount / componentWillUnmount на использование getDerivedStateFromProps и наблюдение за параметром отображения
— вынести логику управления данными в компонент выше, а в модалке лишь отображать то, что нужно

Добавлено через 30 минут
Вообще я в api вижу свойство destroyOnClose, можно его попробовать использовать, мб тогда будет отрабатывать componentWillUnmount.
Либо сделать костыль по 2 варианту через afterClose.
https://ant.design/components/modal/#API

30 / 24 / 11
Регистрация: 16.06.2020
Сообщений: 130

ЦитатаСообщение от Ovederax Посмотреть сообщение

Варианты зависят от задачи

Хотел вынести все модальные диалоги, используемые в приложении в отдельную категорию, чтобы можно было использовать любой модальный диалог в любом месте приложения.
Предполагал сделать что то подобное:

1 2 3 4 5 6 7 8
render() { return ( Modal visible={this.props.conditionToShowAny} > {this.props.conditionToShow1 && ModalContent1 />} {this.props.conditionToShow2 && ModalContent2 />} {this.props.conditionToShow3 && ModalContent3 />} Modal> )}

Т.е. сама обертка модального окна общая для всех модальных контентов, а конкретный контент, который мы хотим показать в данный момент выбирается через значение переменной в redux.
И я предполагал, что Не используемые в данный момент компоненты будут рельно выгружены, поэтому подмена событий componentDidMount / componentWillUnmount другими меня не устроит. Вариант с «ручной» выгрузкой мне тоже кается костыльным.

Если нельзя заставить компонент не монтировать заранее контент, пожалуй, лучшем решением будет перенести обертку в каждый контент-компонент индивидуально. Кстати я попробовал так сделать — эффект плавности не пропал.

342 / 304 / 135
Регистрация: 14.03.2015
Сообщений: 1,136
Записей в блоге: 1

winch, А что если вашу универсальную модальную обертку оставить как есть, а сам компонент для отображения внутри передавать через props?

603 / 403 / 212
Регистрация: 30.04.2017
Сообщений: 743

Лучший ответ

Сообщение было отмечено winch как решение

Решение

ЦитатаСообщение от winch Посмотреть сообщение

И я предполагал, что Не используемые в данный момент компоненты будут рельно выгружены, поэтому подмена событий componentDidMount / componentWillUnmount другими меня не устроит.

ЦитатаСообщение от winch Посмотреть сообщение

Если нельзя заставить компонент не монтировать заранее контент, пожалуй, лучшем решением будет перенести обертку в каждый контент-компонент индивидуально. Кстати я попробовал так сделать — эффект плавности не пропал.

ну ок, а это вы пробовали?

ЦитатаСообщение от Ovederax Посмотреть сообщение

Вообще я в api вижу свойство destroyOnClose, можно его попробовать использовать, мб тогда будет отрабатывать componentWillUnmount.

монтируется и размонтируется при показе и скрытии
https://stackblitz.com/edit/re. e=index.js

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
import React, { useState } from "react"; import ReactDOM from "react-dom"; import "antd/dist/antd.css"; import { Modal, Button } from "antd"; class ModalContentOne extends React.Component { componentDidMount() { console.log("mount one"); } componentWillUnmount() { console.log("unmount one"); } render() { return div>1div>; } } class ModalContentTwo extends React.Component { componentDidMount() { console.log("mount two"); } componentWillUnmount() { console.log("unmount two"); } render() { return div>2div>; } } const getComponent = variant => { switch (variant) { case 0: return ModalContentOne />; case 1: return ModalContentTwo />; } }; const App = () => { const [variant, setVariant] = useState(0); const [isModalVisible, setIsModalVisible] = useState(false); const showChoseVariant = () => { if (variant === 0) { setVariant(1); } else { setVariant(0); } }; const showModal = () => { setIsModalVisible(true); }; const close = () => { setIsModalVisible(false); }; const component = getComponent(variant); return ( <> Button type="primary" onClick={showModal}> Open Modal Button>{" "} Button type="primary" onClick={showChoseVariant}> Switch variant Button> Modal destroyOnClose title="Modal" visible={isModalVisible} onOk={close} onCancel={close} > {component} Modal>  ); }; ReactDOM.render(App />, document.getElementById("container"));

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *