JavaRush /Курсы /Модуль 3: React /Обсуждение проблем и типичных ошибок при работе с API и A...

Обсуждение проблем и типичных ошибок при работе с API и AsyncStorage

Модуль 3: React
24 уровень , 9 лекция
Открыта

Типичные проблемы при работе с API в React Native

Что же, настало время обсудить типичные проблемы и ошибки, которые могут возникнуть при работе с API и AsyncStorage, а также пути их решения.

Ошибка №1: неверный обработчик ошибок

Нередко разработчики забывают обрабатывать ошибки при выполнении API-запросов. Например, если сервер отвечает кодом 404 или 500, приложение может просто "упасть". Представьте, вы нажали кнопку "Получить данные", а в ответ — просто белый экран. Это явно не то, чего хотелось бы пользователям.

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

const fetchData = async () => {
  try {
    const response = await fetch('https://example.com/api/data');
    if (!response.ok) {
      throw new Error(`Ошибка: ${response.status}`); // Проверка статуса
    }
    const data = await response.json();
    console.log('Полученные данные:', data);
  } catch (error) {
    console.error('Ошибка при выполнении запроса:', error.message);
    // Покажем пользователю понятное сообщение
    Alert.alert('Ошибка', 'Не удалось загрузить данные. Попробуйте позже.');
  }
};

Здесь мы проверяем response.ok и выбрасываем ошибку, если что-то пошло не так. Это позволяет унифицировать обработку ошибок.

Ошибка №2: асинхронный код "на свободе"

Когда вы используете async/await, важно помнить, что каждую асинхронную функцию нужно обернуть в try/catch. Если вы игнорируете это правило, то неперехваченные ошибки "пройдут мимо", и приложение может вести себя непредсказуемо.

Например, такой код:

const getData = async () => {
    const response = await fetch('https://example.com/api/data');
    const data = await response.json();
    return data;
};

Если сервер недоступен, это приведет к ошибке, которая нигде не будет обработана. Всегда используйте try/catch или методы обработки ошибок, такие как .catch().

Ошибка №3: неразумный подход к повторным запросам

Если ваш API-запрос терпит неудачу, что вы делаете? Попробовать повторить его снова? Или паникуете? Здесь стоит внедрить стратегию повторных попыток:

const fetchDataWithRetries = async (url: string, retries: number = 3): Promise<any> => {
  while (retries > 0) {
    try {
      const response = await fetch(url);
      if (response.ok) return await response.json();
      throw new Error(`Ошибка: ${response.status}`);
    } catch (error) {
      retries -= 1;
      if (retries === 0) {
        throw new Error('Превышено количество попыток');
      }
      console.log('Повтор запроса...');
    }
  }
};

Такой механизм полезен для временных сбоев, например, при плохом соединении.

Ошибка №4: забытая отмена запросов

При работе с fetch или Axios легко забыть, что запросы продолжают выполняться даже после того, как пользователь покинул экран. Это может привести к утечкам памяти или попыткам обновить состояние несуществующего компонента.

Для fetch решения нет, кроме реализации дополнительных механизмов, но с Axios становится проще:

import axios from 'axios';

const fetchData = async () => {
  const source = axios.CancelToken.source();
  try {
    const response = await axios.get('https://example.com/api/data', {
      cancelToken: source.token,
    });
    console.log(response.data);
  } catch (error) {
    if (axios.isCancel(error)) {
      console.log('Запрос был отменён');
    } else {
      console.error(error);
    }
  }
  return () => {
    source.cancel('Операция отменена пользователем');
  };
};

Ошибка №5: игнорирование CORS

Многие API требуют настроек CORS. Если вы видите ошибку "No Access-Control-Allow-Origin header", это связано с ограничениями браузера. Решение обычно кроется на стороне сервера. Но в случае мобильных приложений React Native это встречается реже, так как они не ограничиваются браузерными политикам.

Ошибки при использовании AsyncStorage

Ошибка №1: неправильная сериализация

AsyncStorage работает с данными в формате строки. Если вы пытаетесь сохранить объект без сериализации в JSON, это приведёт к ошибке или некорректным данным:

// Неправильно
await AsyncStorage.setItem('user', { name: 'John Doe' }); // Ошибка

// Правильно
await AsyncStorage.setItem('user', JSON.stringify({ name: 'John Doe' }));

И не забывайте "разбирать" данные обратно:

const user = await AsyncStorage.getItem('user');
const parsedUser = user ? JSON.parse(user) : null;
console.log(parsedUser.name);

Ошибка №2: отсутствие проверки данных

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

const rawValue = await AsyncStorage.getItem('theme');
const theme = rawValue === 'dark' || rawValue === 'light' ? rawValue : 'light'; // Обрабатываем ошибку

Ошибка №3: Утечка памяти из-за выборки данных

AsyncStorage — асинхронная операция, и если её не завершить до размонтирования компонента, может возникнуть утечка памяти:

useEffect(() => {
  let isMounted = true;
  const loadData = async () => {
    const data = await AsyncStorage.getItem('key');
    if (isMounted) {
      // Действие только если компонент ещё в DOM
      setState(data);
    }
  };

  loadData();

  return () => { isMounted = false; }; // Флаг размонтирования
}, []);

Ошибка №4: проблемы с производительностью

Постоянное обращение к AsyncStorage внутри циклов или частая выборка данных может замедлить приложение. Старайтесь кэшировать данные в состоянии (useState или Redux):

useEffect(() => {
  const fetchFromStorage = async () => {
    const data = await AsyncStorage.getItem('key');
    setData(data);
  };
  fetchFromStorage();
}, []);

// Используем `data` из состояния, а не извлекаем её снова при каждом рендере

Советы по оптимизации

1. Используйте библиотеки-обёртки

Для больших проектов есть смысл использовать библиотеки вроде react-query или redux-persist, которые автоматически кэшируют данные и упрощают работу с хранилищем.

2. Логируйте и анализируйте

Когда что-то идёт не так, полезно иметь хорошие логи. Например, добавьте сервисы Sentry или LogRocket для отслеживания ошибок в приложении.

3. Тестируйте асинхронность

Пользовательские тесты, эмуляция медленного соединения и даже инструменты вроде Postman помогут заранее выявить слабые места.

2
Задача
Модуль 3: React, 24 уровень, 9 лекция
Недоступна
Повтор API-запроса в случае сбоя
Повтор API-запроса в случае сбоя
3
Опрос
Введение в AsyncStorage, 24 уровень, 9 лекция
Недоступен
Введение в AsyncStorage
Введение в AsyncStorage
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ