Повторно использованная асинхронная функция для установки различных переменных состояния

Вопрос или проблема

У меня есть асинхронная функция, которая извлекает объект из базы данных (Referral). В дополнение к основному запросу, различные части приложения также извлекают вспомогательные Referral с помощью точно такой же функции и ее логики.

Асинхронная функция не может ничего вернуть, поэтому ее не можно использовать как универсальное возвращаемое значение. Вместо этого нам нужно установить переменную состояния с результатами из нее.

Если я сделаю

const [mainReferral, setMainReferral] = useState<Referral|null>(null);

// Извлечение основного реферала
const fetchReferral = async (referralId:string) => {
    const response = await get<any>("/referral/" + referralId);
    // Много логики ниже, например
    response['specialDerivedField1'] = ...;
    response['specialDerivedField2'] = ...;
    //...
    setMainReferral(response);
}

Это обрабатывает только единственный случай основного реферала. У меня также может быть

const [auxReferral1, setAuxReferral1] = useState<Referral|null>(null);
const [auxReferral2, setAuxReferral2] = useState<Referral|null>(null);
//...

Мне действительно нужно добавлять разные параметры в эту функцию, чтобы решить, что установить с помощью if-else? Это не кажется мне очень надежным.

const fetchReferral = async (referralId:string, case1:boolean, case2:boolean) => {
   //... 
   if (case1) 
      setAuxReferral1(response);
   else if (case2) {
      setAuxReferral2(response);
   else {
      setMainReferral(response);
   }
}

Есть ли другие лучшие практики для этого? Или, возможно, передавать строку для имени переменной состояния и затем находить установщик по имени (не уверен, поддерживает ли это React)?

Мне также хотелось бы изолировать эту утилиту в отдельном файле утилиты, который не работает с состоянием, но как асинхронную функцию это будет невозможно, я предполагаю?

Асинхронная функция не может ничего вернуть

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

Ваша async функция действительно может возвращать результат:

const fetchReferral = async (referralId:string) => {
  // существующий код, затем...
  return response;
}

И любой компонент может обновить состояние с этим результатом:

// используя await:
const referral = await fetchReferral(someValue);
setMainReferral(referral);

// или используя .then():
fetchReferral(someValue).then(setMainReferral);

В качестве альтернативы, если вы предпочитаете инкапсулировать обработку Promise в самой функции, вы можете передать установщики состояния как обратный вызов. Например:

const fetchReferral = async (referralId:string, callback:(x:any)=>{}) => {
  // существующий код, затем...
  callback(response);
}

И любой компонент просто передаст функцию как обратный вызов:

fetchReferral(someValue, setAuxReferral1);

Другим вариантом может быть обертка операции и состояния в пользовательский хуку. Например:

const useReferral = function () => {
  const [referral, setReferral] = useState();

  const fetchReferral = async (referralId:string) => {
    // существующий код, затем...
    setReferral(response);
  }

  return {
    referral, fetchReferral
  };
};

И любой компонент просто будет использовать этот хук:

const { referral, fetchReferral } = useReferral();

// где-то в логике вашего компонента:
fetchReferral(someValue);

// и используйте "referral" как значение состояния

Ответ или решение

Эффективное использование асинхронной функции для установки состояний в React

Вопрос, с которым вы столкнулись, касается оптимизации кода в React-приложении при работе с асинхронными функциями. Вам нужно извлекать данные из базы данных и обновлять множественные состояния без усложнения логики. Давайте разберем несколько подходов к решению проблемы.

1. Понимание возвращаемых значений асинхронных функций

Похоже, существует недопонимание относительно возвращаемых значений асинхронных функций. Асинхронные функции в JavaScript действительно могут возвращать значения. Например, вы можете вернуть данные, которые затем использует компонент React для обновления состояния:

const fetchReferral = async (referralId: string) => {
    const response = await get<any>(`/referral/${referralId}`);
    // Дополнительная логика...
    return response;
};

// Использование await для установки состояния
const mainReferral = await fetchReferral(someValue);
setMainReferral(mainReferral);

// Или с использованием .then()
fetchReferral(someValue).then(setMainReferral);

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

2. Передача колбеков

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

const fetchReferral = async (referralId: string, callback: (x: any) => void) => {
    const response = await get<any>(`/referral/${referralId}`);
    // Дополнительная логика...
    callback(response);
};

// В компоненте
fetchReferral(someValue, setAuxReferral1);

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

3. Создание пользовательского хука

Однако наиболее элегантным решением может стать создание пользовательского хука, который будет инкапсулировать как логику получения данных, так и состояние. Это позволит вам повысить повторное использование кода и минимизировать избыточность:

const useReferral = () => {
    const [referral, setReferral] = useState<Referral | null>(null);

    const fetchReferral = async (referralId: string) => {
        const response = await get<any>(`/referral/${referralId}`);
        // Дополнительная логика...
        setReferral(response);
    };

    return { referral, fetchReferral };
};

// Использование в компоненте
const { referral, fetchReferral } = useReferral();
fetchReferral(someValue);

С помощью пользовательского хука вы получите чистый и понятный API для работы с рефералами, что значительно упростит вашу логику и сократит количество повторяющегося кода.

Заключение

Представленные выше методы помогут эффективно управлять асинхронными операциями и состоянием в вашей React-приложении. Выберите наиболее подходящий для вашего случая вариант, будь то возвращение значений из асинхронной функции, передача колбеков или использование пользовательских хуков. Это не только улучшит читаемость и поддержку вашего кода, но и повысит его производительность.

Оцените материал
Добавить комментарий

Капча загружается...