Продолжайте получать следующее сообщение об ошибке в React Native, действительно не понимаю, откуда оно
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
У меня есть такой простой компонент:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isLoggedIn: false,
}
}
componentDidMount(){
this.fetchToken()
}
async fetchToken(){
const access_token = await AsyncStorage.getItem('access_token')
if (access_token !== null) {
this.setState({ isLoggedIn: true })
}
}
render() {
const login = this.state.isLoggedIn
if (login) {
return <NavigatorLoggedIn />
} else {
return <Navigator/>
}
}
}
Спасибо за ответ! Обновил компонент с вашими предложениями. Оригинальное предупреждение все еще там; (
componentDidMount() запускается после рендеринга, поэтому обновленное состояние не отображается / не доступно в render(). Тогда я предполагаю, что этот компонент в любом случае размонтируется через render(), и поэтому вызов fetchToken() после факта вызывает утечку памяти в соответствии с сообщением об ошибке.
@radarbob так думал! есть предложения по решению? Сам пытаюсь найти решение
Вне руки: (1) сделайте это в render() на самом верху. (2) сделайте это в конструкторе. В любом случае используйте другая форма setState(), который принимает функцию; потому что setState() принципиально асинхронный
Возможный дубликат Предупреждение реакции о setState в отключенном компоненте





Вы можете использовать это:
componentDidMount() {
this.function()
}
function = async () => {
const access_token = await AsyncStorage.getItem('access_token')
if (access_token !== null) {
this.setState({ isLoggedIn: true })
}
}
Или вы можете вызвать в function в constructor.
Я надеюсь, что это поможет вам...
Спасибо за быстрый ответ! Пробовал, но получил такое же предупреждение в исходном вопросе
Обратите внимание: не вызывайте функции async / await в конструкторе. Конструктор должен инициализировать компонент и вернуть его как можно скорее. Если вам нужно дождаться асинхронной функции, вызовите ее в componentDidMount.
вам нужно использовать переменную isMounted.
componentDidMount(){
this.setState({ isMounted = true });
const access_token = await AsyncStorage.getItem('access_token')
if (access_token !== null && this.isMounted) {
this.setState({ isLoggedIn: true })
}
}
componentWillUnmount(){
this.setState({ isMounted = false });
}
Или, если вы используете Axios, вы можете использовать функцию запроса отмены axios. это здесь: https://github.com/axios/axios#cancellation
Спасибо за быстрый ответ! Пробовал, но setState isLoggedIn не работает таким образом
Я не понимаю. Если компонент все еще смонтирован, setState работает нормально.
оператор if не запускается, && this.isMounted не работает
Вы пытались использовать обещание или обратный вызов вместо async / await?
Документы RN говорят, что не следует вызывать setState при отключении: reactjs.org/docs/react-component.html#componentwillunmount
Будет работать:
let self;
class App extends React.Component {
constructor(props) {
super(props)
self = this;
this.state = {
isLoggedIn: false,
}
}
componentDidMount(){
this.fetchToken()
}
async fetchToken(){
const access_token = await AsyncStorage.getItem('access_token')
if (access_token !== null) {
self.setState({ isLoggedIn: true })
}
}
render() {
const login = self.state.isLoggedIn
if (login) {
return <NavigatorLoggedIn />
} else {
return <Navigator/>
}
}
}
Для меня я решил это, перезапустив сервер с помощью "yarn start" или "npm start".
Вы можете попробовать это:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isLoggedIn: false,
}
}
_isMounted = false;
componentDidMount(){
this._isMounted = true;
this.fetchToken()
}
async fetchToken(){
const access_token = await AsyncStorage.getItem('access_token')
if (access_token !== null && this._isMounted) {
this.setState({ isLoggedIn: true })
}
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const login = this.state.isLoggedIn
if (login) {
return <NavigatorLoggedIn />
} else {
return <Navigator/>
}
}
}
При использовании _isMounted setState вызывается только в том случае, если компонент смонтирован. Размонтирование не дожидается завершения асинхронного вызова. В конце концов, когда асинхронный вызов завершается, компонент уже размонтирован и поэтому не может установить состояние. Для этого ответ просто проверяет, смонтирован ли компонент, перед установкой состояния.
Отмена всех асинхронных операций - одно из решений
Вы должны инициализировать состояние внутри конструктора, а не за его пределами. И используйте
this.state, а не толькоstate. Я также не стал бы применять атрибутasyncк методам жизненного цикла React по умолчанию, лучше оставить их как есть. Создайте для этого отдельную функцию компонентаasync/await, затем вызовите ее вcomponentDidMount.