JavaRush /Курсы /Модуль 3: React /Типизация MFA-данных и работы с ними в компонентах

Типизация MFA-данных и работы с ними в компонентах

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

Основные интерфейсы данных MFA

Вот пример, как мы можем типизировать данные, относящиеся к MFA. Предположим, у нас есть API, которое обрабатывает:

  1. Генерацию и отправку кода.
  2. Подтверждение кода пользователем.

Начнём с создания интерфейсов:

// Типизация данных, отправляемых на сервер для генерации кода MFA
export interface GenerateMFARequest {
  userId: string; // Идентификатор пользователя
}

// Ответ от сервера после генерации кода
export interface GenerateMFAResponse {
  success: boolean; // Успешно ли сгенерирован код
  message?: string; // Сообщение об ошибке (в случае неудачи)
}

// Типизация данных для подтверждения кода MFA
export interface ConfirmMFARequest {
  userId: string; // Идентификатор пользователя
  code: string;   // Введённый код подтверждения
}

// Ответ от сервера после подтверждения кода
export interface ConfirmMFAResponse {
  success: boolean; // Успешно ли подтверждение
  token?: string;  // JWT-токен в случае успешного подтверждения
  message?: string; // Сообщение об ошибке (при неудаче)
}

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

Работа с типизированными данными в компонентах

После того как мы определили интерфейсы, можно приступить к использованию этих данных в наших компонентах.

Предположим, у нас есть компонент, который позволяет пользователю ввести код MFA для подтверждения. Мы будем отправлять запрос на сервер и обрабатывать ответ.

Вот пример кода такого компонента:

import React, { useState } from "react";
import axios from "axios";
import { ConfirmMFARequest, ConfirmMFAResponse } from "./types"; // Импорт интерфейсов

const ConfirmMFA = () => {
  const [code, setCode] = useState<string>(""); // Состояние для ввода кода
  const [error, setError] = useState<string | null>(null); // Состояние для ошибок
  const [loading, setLoading] = useState<boolean>(false); // Состояние загрузки

  const handleConfirm = async () => {
    setLoading(true);
    setError(null);

    // Формируем запрос
    const requestData: ConfirmMFARequest = {
      userId: "12345", // ID пользователя, захардкожен для примера
      code,
    };

    try {
      // Отправляем запрос на сервер
      const response = await axios.post<ConfirmMFAResponse>(
        "/api/confirm-mfa",
        requestData
      );

      if (response.data.success) {
        alert("MFA подтверждена, токен: " + response.data.token);
      } else {
        setError(response.data.message || "Неизвестная ошибка");
      }
    } catch (err) {
      setError("Ошибка сети или сервера");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h3>Введите код MFA</h3>
      <input
        type="text"
        value={code}
        onChange={(e) => setCode(e.target.value)}
        placeholder="Введите код"
      />
      <button onClick={handleConfirm} disabled={loading}>
        {loading ? "Подтверждение..." : "Подтвердить"}
      </button>
      {error && <p style={{ color: "red" }}>{error}</p>}
    </div>
  );
};

export default ConfirmMFA;

Что здесь происходит?

  1. Состояние code отвечает за хранение текущего ввода пользователя.
  2. При клике на кнопку "Подтвердить" отправляется запрос на сервер с кодом и идентификатором пользователя.
  3. Мы типизируем запрос ConfirmMFARequest и ответ ConfirmMFAResponse, чтобы избежать ошибок при обработке данных.
  4. Возможные ошибки (например, неверный код или сетевые проблемы) обрабатываются и отображаются пользователю.

Расширяем компонент: использование хуков

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

Создаём хук для подтверждения MFA

import { useState } from "react";
import axios from "axios";
import { ConfirmMFARequest, ConfirmMFAResponse } from "./types";

export const useConfirmMFA = () => {
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  const confirmMFA = async (requestData: ConfirmMFARequest): Promise<string | null> => {
    setLoading(true);
    setError(null);

    try {
      const response = await axios.post<ConfirmMFAResponse>(
        "/api/confirm-mfa",
        requestData
      );

      if (response.data.success) {
        return response.data.token || null;
      } else {
        setError(response.data.message || "Неизвестная ошибка");
        return null;
      }
    } catch (err) {
      setError("Ошибка сети или сервера");
      return null;
    } finally {
      setLoading(false);
    }
  };

  return { confirmMFA, loading, error };
};

Использование хука в компоненте

Теперь компонент ConfirmMFA будет выглядеть проще:

import React, { useState } from "react";
import { useConfirmMFA } from "./useConfirmMFA";

const ConfirmMFA = () => {
  const [code, setCode] = useState<string>(""); // Состояние для ввода кода
  const { confirmMFA, loading, error } = useConfirmMFA();

  const handleConfirm = async () => {
    const token = await confirmMFA({ userId: "12345", code });
    if (token) {
      alert("MFA подтверждена, токен: " + token);
    }
  };

  return (
    <div>
      <h3>Введите код MFA</h3>
      <input
        type="text"
        value={code}
        onChange={(e) => setCode(e.target.value)}
        placeholder="Введите код"
      />
      <button onClick={handleConfirm} disabled={loading}>
        {loading ? "Подтверждение..." : "Подтвердить"}
      </button>
      {error && <p style={{ color: "red" }}>{error}</p>}
    </div>
  );
};

export default ConfirmMFA;

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

2
Задача
Модуль 3: React, 16 уровень, 3 лекция
Недоступна
Создание интерфейса для данных MFA
Создание интерфейса для данных MFA
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ