ReactJS - уничтожить старый экземпляр компонента и создать новый

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

Представьте, что у меня есть простой компонент реакции, который называется «Контейнер». Компонент-контейнер имеет «div» внутри метода-рендеринга, который содержит другой компонент, называемый «ChildContainer». «Div», окружающий «ChildContainer», имеет идентификатор wrappingDiv.

Пример:

render() {
  <Container>
    <div id = "wrappingDiv">
      <ChildContainer/>
    </div>
  </Container
}

Как я могу уничтожить экземпляр компонента "ChildContainer" и создать совершенно новый. Это означает, что вызывается ComponentWillUnmount старого экземпляра и вызывается ComponentDidMount нового компонента.

Я не хочу, чтобы старый компонент обновлялся путем изменения состояния или свойств.

Мне нужно это поведение, потому что у внешней библиотеки от нашей компании-партнера есть библиотека, которая меняет dom-элементы, и в React я получу исключение «Узел не найден», когда я обновлю компонент.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
17
0
17 726
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы дадите компоненту key и измените этот key при повторном рендеринге, старый экземпляр компонента отключится, а новый будет смонтирован:

render() {
  ++this.childKey;
  return <Container>
    <div id = "wrappingDiv">
      <ChildContainer key = {this.childKey}/>
    </div>
  </Container>;
}

У ребенка каждый раз будет новый key, поэтому React сочтет его частью списка и выбросит старый, создав новый. Любое изменение состояния вашего компонента, вызывающее его повторную визуализацию, приведет к тому, что дочерний элемент будет демонтирован и воссоздан заново.

Живой пример:

class Container extends React.Component {
  render() {
    return <div>{this.props.children}</div>;
  }
}

class ChildContainer extends React.Component {
  render() {
    return <div>The child container</div>;
  }
  componentDidMount() {
    console.info("componentDidMount");
  }
  componentWillUnmount() {
    console.info("componentWillUnmount");
  }
}

class Example extends React.Component {
  constructor(...args) {
    super(...args);
    this.childKey = 0;
    this.state = {
      something: true
    };
  }

  componentDidMount() {
    let timer = setInterval(() => {
      this.setState(({something}) => ({something: !something}));
    }, 1000);
    setTimeout(() => {
      clearInterval(timer);
      timer = 0;
    }, 10000);
  }
  
  render() {
    ++this.childKey;
    return <Container>
      {this.state.something}
      <div id = "wrappingDiv">
        <ChildContainer key = {this.childKey}/>
      </div>
    </Container>;
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById("root")
);
<div id = "root"></div>

<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>

Сказав это, вполне может быть лучший ответ на вашу основную проблему с плагином. Но вышеупомянутый вопрос касается фактически заданного вопроса ... :-)

спасатель жизни, 683к реп это что-то значит :)

slash197 29.01.2019 10:36

Привет, Краудер, как мне это сделать в ответных хуках?

satyanarayan mishra 03.01.2021 13:34

Определенно спаситель

Sagar 25.05.2021 05:45

Используя хуки, сначала создайте переменную состояния для хранения ключа:

const [childKey, setChildKey] = useState(1);

Затем используйте хук useEffect для обновления ключа при рендеринге:

useEffect(() => {
   setChildKey(prev => prev + 1);
});

Примечание: вы, вероятно, хотите, чтобы что-то в параметре массива в useEffect обновляло ключ только при изменении определенного состояния

Другие вопросы по теме