См. здесь: https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html А также здесь: Как отменить выборку на componentWillUnmount А здесь: смонтированный антипаттерн, отслеживание собственного свойства
В обоих случаях упоминаются 3 подхода:
promise.resolve проверьте this.IsMounted(), который React вернет вам правильно, если `Compounted Has Unmountedpromise.resolve проверьте _isMounted, который вы вручную отследили методом ComponentWillUnmount().promise никогда не разрешил. И это решит все ваши проблемы и сделает его прекрасным.За исключением третьего случая, ваш promise будет error(), но также может быть error() в других случаях (например, API не работает).
Так что на самом деле 3-й вариант сводится к:
- В вашем promise.error проверьте errorPayload.IsCancelled, который вы вручную отследили в объекте cancellablePromise, который, в свою очередь, был запущен ручным вызовом в ComponentWillUnmount.
Итак, все три практически идентичны:
When you are handling your
promiseoutcomes, check the value of this variable that is directly tied to whether the component has alreadyunmounted.
Почему они утверждают, что 3-й вариант лучше остальных 2-х, а 1-й вариант — это антипаттерн.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Давайте представим, что действие, которое вызовет будущий вызов setState, выполняет много вычислений или выполняет множество сетевых запросов. Все эти ресурсы будут использованы, а затем когда-нибудь в будущем, когда промис разрешится, он поймет, что вся работа не нужна, так как пользователь уже покинул эту часть страницы, и вся работа будет отброшена. Это плохо для производительности и использования сети/памяти, особенно если у вас есть много элементов, которые появляются и исчезают. Если вы выберете вариант 3, только небольшое количество ресурсов будет потрачено впустую, пока не будет достигнута следующая точка остановки и ресурсы не будут освобождены. Я предполагаю, что они удалили 1) чтобы заставить кодировщиков использовать 3) и предложили 2) для случаев, когда миграция невозможна/сложна.
@brondahl зависит от того, как вы отмените основные действия.
Интересно ... Однако я не сталкивался с этим раньше ... на основе этой страницы у вас все еще есть точно такая же логика обещаний, только теперь проверка if (err.name === 'AbortError'), а не if (err.isCancelled). (1/2)
Что касается остановки работы, я был бы очень удивлен, если бы это ДЕЙСТВИТЕЛЬНО говорило серверу прекратить работу (т.е. убить поток сервера), если это реализуется на уровне браузера. (Поскольку для этого потребуется, чтобы каждый браузер знал, как отправить это сообщение на каждый сервер и серверную инфраструктуру). Я подозреваю, что это просто говорит браузеру не слушать ответ сервера. Таким образом, все, что вы делаете, — это продвигаете принцип «а потом ничего не делать» еще на один недорогой шаг вперед. (2/2)
Компонентный метод isMounted устарел. Его больше нельзя использовать в React 16.
Встроенного состояния _isMounted нет, оно должно определяться пользователем в хуках жизненного цикла компонента. В какой-то степени это вопрос предпочтений. Проблема в том, что для доступа к this._isMounted требуется, чтобы цепочка обещаний была связана с экземпляром компонента.
Это не проблема для отменяемых обещаний. Более того, этот шаблон позволяет фактически отменить асинхронный процесс, например. Axios фактически отменяет запрос XHR во время отмены. Тем не менее, чтобы это работало, требуется, чтобы вся цепочка обещаний знала об отмене. Это может быть утомительно, так как отмена не поддерживается в собственных промисах, включая async..await.
Наблюдаемые объекты предоставляют еще более мощные способы управления выполнением. Есть единственная точка (подписка), которая способна отменить всю цепочку, вызвав функцию отписки:
const unsubscribe = fetchData()
.mergeMap(asynchronousProcessing)
.mergeMap(yetAnotherAsynchronousProcessing)
.subscribe(data => this.setState(data));
Ключевым элементом здесь является то, что if (this.isMounted()) { setState(...) } является антипаттерном в целом. Это может привести к подавлению полезных предупреждений, поэтому к его появлению следует относиться с подозрением, поскольку в большинстве случаев оно представляет собой возможность скрыть реальные проблемы. Таким образом, даже в тех случаях, когда его поведение функционально такое же, как и у какого-либо другого подхода, этот другой подход предпочтительнее.
В случае вызовов API вполне разумно игнорировать результаты промиса, потому что они больше не актуальны. Использование отмененного обещания синтаксически и семантически связывает логику того, следует ли игнорировать результат, конкретно с вызовом API, что предотвращает любую возможность того, что будущие разработчики случайно используют код в другом контексте и потенциально подавляют значимые предупреждения.
Хотя разница может быть семантической, сама семантика имеет значение для удобства сопровождения. В этом случае отменяемое обещание служит для структурного объединения проблем, привязывая поведение, которое может быть проблемой в целом, к конкретной ситуации, в которой оно допустимо.
Я понимаю... мы говорим, что вызовы API в изоляции являются разумным использованием isMounted(). Но если мы используем отменяемые промисы, то это позволяет нам сказать: «Теперь isMounted() НИКОГДА не является правильным». Который тогда более удобен в сопровождении и лучше защищен для этих других случаев.
Другая аналогия: GOTO (канонически) считаются вредными. Но if, while, break, continue и switch, по сути, просто делают одно и то же, но объявляют приемлемые ситуации, в которых разумно использовать эту концепцию.
Неправда - отмена обещания НИЧЕГО не делает, пока обещание не будет разрешено - это не токены отмены, которые передаются серверу, выполняющему работу, - это просто флаги того, как обещание разрешается.