Реакция: setState в несмонтированном компоненте - PullRequest
3 голосов
/ 03 августа 2020

Немного поздно, но я недавно начал изучать предупреждения о размонтированном setState, выдаваемые React, где они упоминают, что это может привести к утечкам памяти.

В блоге упоминается, как isMounted () или наличие собственного isMounted - это антипаттерн https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

В твиттере Дэн Абрамов объясняет, почему это антипаттерн и как он может привести утечкам памяти. Суть в том, что обработчик обещания then / catch по-прежнему будет содержать ссылку на отключенный компонент дольше, чем требуется. В идеале у нас не должно быть этой ссылки после размонтирования компонента

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

Идеальная реализация, предложенная Дэном, - это либо иметь отменяемые обещания, которые могут внутренне избавиться от этих ссылок на компоненты, либо иметь собственную реализацию отменяемого обещания, которая может отклонить обещание только в случае его отмены, но должна удалите все ссылки на компонент.

Теперь я действительно не понимаю, как работает эта эталонная штука и как это решается с помощью решения, предложенного в сообщении в блоге (которое, похоже, отклоняет обещание, если оно было отменен, но у него нет способа удалить ссылку на компонент)

Вот что я хочу понять:

  • Если в компоненте A, в обещании. тогда (или поймать) мы не Для this это будет означать, что компонент не упоминается, и даже если он размонтирован, это не будет утечкой памяти при фактическом вызове обработчика then?
  • Если мы зарегистрируем then обработчик в компоненте A для обещания, как долго он живет? Удаляется ли это когда-нибудь во время выполнения? Будет ли он удален после размонтирования компонента, поскольку компонент больше не сохраняет ссылку на обещание и, следовательно, обратный вызов then. Однако в этом случае обратный вызов then сразу после установки компонента все равно будет выполняться, как это было бы запланировано в очереди микрозадач, но это не произойдет в любое время позже? (Это может быть причиной того, что мы видим это предупреждение только один раз, когда компонент размонтируется)
  • Как мы можем вручную удалить ссылку на компонент при отмене обещания (как предлагает Дэн в ветке твиттера), чтобы избежать утечки памяти?
  • решение, предложенное в блоге, все равно приведет к утечке памяти? (Хотя это решение может быть более семантически правильным по сравнению с решением isMounted)
...