Здравствуйте читатели и слушатели 🙂

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

  1. использоватьредукционный крюк
  2. Контекстный API
  3. Компонент
  4. События

1. Используйте редукционный крюк

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

Как использовать хук useReducer

Чтобы использовать хук useReducer, вам сначала нужно определить функцию редуктора. Функция редуктора принимает текущее состояние и действие в качестве входных данных и возвращает новое состояние. Объект действия можно использовать для передачи данных функции редуктора.

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

Синтаксис хука useReducer в ReactJS:

const [state, dispatch] = useReducer(reducer, initialState);
  • reducer — это функция, которая принимает текущее состояние и действие в качестве входных данных и возвращает новое состояние.
  • initialState — начальное состояние компонента.
  • state — это ссылка на текущее состояние компонента.
  • dispatch — это функция, которая используется для отправки действий функции редуктора.

Пример использования хука useReducer:

import { useReducer } from "react";

const initialState = {
    dynamicData: null,
    isLoading: false,
    error: null,
}
const reducer = (state = initialState, { type, payload }) => {
    switch (type) {
        case "GET_DATA_PENDING":
            return { ...state, isLoading: true, };
        case "GET_DATA_SUCCESS":
            return { ...state, dynamicData: payload, isLoading: false, };
        case "GET_DATA_SUCCESS":
            return { ...state, error: payload, isLoading: false, };
        default:
            return state;
    }

}
export default function App() {
    const [state, dispatch] = useReducer(reducer, initialState);

    const handleGetDynamicData = () => {
        try {
            dispatch({ type: "GET_DATA_PENDING" });
            // DO API Calling
            dispatch({ type: "GET_DATA_SUCCESS", payload: { /* Dynamic Getted Data */ } });
        } catch (error) {
            dispatch({ type: "GET_DATA_FAILED", payload: error });
        }
    }
    return (
        <div>
            <button onClick={handleGetDynamicData}>GET DYNAMIC DATA</button>
        </div>
    );
}



Если вы хотите узнать больше о useReducer, перейдите по этой официальной ссылке на документацию.



2. Контекстный API

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

Context API состоит из двух основных компонентов:

  • Поставщик контекста: этот компонент создает контекст и предоставляет доступ к его данным.
  • Потребитель контекста: этот компонент потребляет контекст и его данные.

Как использовать контекстный API

Чтобы использовать Context API, сначала необходимо создать поставщика контекста. Это можно сделать, создав компонент, расширяющий класс ContextProvider, и предоставив объект контекста в качестве реквизита.

import React, { Context, useContext } from 'react';

const MyContext = React.createContext(null);

const MyContextProvider = ({ children }) => {
  const [data, setData] = useState(null);

  return (
    <MyContext.Provider value={data}>
      {children}
    </MyContext.Provider>
  );
};

export { MyContext, MyContextProvider };

Создав поставщика контекста, вы можете использовать его для предоставления доступа к его данным в других компонентах. Для этого нужно обернуть компонент, которому нужен доступ к данным, в компонент ContextConsumer.

import React, { useContext } from 'react';
import { MyContext } from './MyContext';

const MyComponent = () => {
  const data = useContext(MyContext);

  return <div>The data is {data}</div>;
};

export default MyComponent;

Преимущества использования контекстного API

Есть несколько преимуществ использования Context API в ваших приложениях React. Вот несколько наиболее важных из них:

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

Если вы хотите узнать больше о Context API, перейдите по этой официальной ссылке на документацию.



3. Компонент

Компонент React — это повторно используемый фрагмент кода, который используется для отображения элементов HTML. Компоненты — это строительные блоки приложений React, и их можно использовать для создания сложных пользовательских интерфейсов.

Как работают компоненты React?

Компоненты React работают, используя функцию рендеринга для возврата HTML-элементов, которые должны отображаться. Функция рендеринга вызывается всякий раз, когда компонент монтируется или обновляется.

Каковы преимущества использования компонентов React?

Использование компонентов React дает много преимуществ, в том числе:

  • Возможность повторного использования. Компоненты можно повторно использовать в приложении, что может помочь уменьшить дублирование кода и повысить удобство сопровождения кода.
  • Масштабируемость: Компоненты могут быть составлены для создания сложных пользовательских интерфейсов, которые могут помочь сделать приложения более удобными в сопровождении и более простыми для тестирования.
  • Производительность. Компоненты можно оптимизировать для повышения производительности, что может помочь повысить общую производительность приложения.

Где я могу узнать больше о компонентах React?

Существует множество доступных ресурсов, которые помогут вам узнать больше о компонентах React. Вот несколько самых популярных ресурсов:

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

Пример простого компонента React:

function Welcome(props) {
  return (
    <h1>Hello, {props.name}</h1>
  );
}

Если вы хотите узнать больше о React Component, перейдите по этой официальной ссылке на документацию.



4. События

События в React JS

Когда пользователь взаимодействует с компонентом React, например, щелкает элемент или печатает в текстовом поле, запускается событие. События обрабатываются обработчиками событий, которые представляют собой функции, вызываемые при возникновении события. Обработчики событий можно прикрепить к любому компоненту React, и их можно использовать для выполнения любых действий, таких как изменение состояния компонента, обновление DOM или выполнение вызова API.

Обработка событий в React JS

Есть два способа обработки событий в React JS:

  • Напрямую: это наиболее распространенный способ обработки событий. Чтобы обработать событие напрямую, вы прикрепляете обработчик события к компоненту, используя свойство onClick. Функция обработчика событий будет вызываться при срабатывании события.
  • Через компонент более высокого порядка: компонент более высокого порядка — это функция, которая принимает компонент в качестве входных данных и возвращает новый компонент. Компоненты более высокого порядка могут использоваться для более централизованной обработки событий.

Синтетические события

React JS использует синтетические события вместо нативных событий DOM. Синтетические события — это объекты, содержащие информацию о событии, такую ​​как тип события, целевой элемент и свойства события. Синтетические события используются для обеспечения согласованной работы компонентов React в разных браузерах.

Распространение событий

Когда событие запускается, оно всплывает вверх по дереву DOM. Это означает, что сначала будет вызываться обработчик событий для ближайшего предка целевого элемента, затем обработчик событий для следующего ближайшего предка и так далее. Распространение события можно остановить, вызвав метод stopPropagation() для объекта события.

Пузырьковое событие

Всплывание событий противоположно распространению событий. Когда событие запускается, оно всплывает в дереве DOM. Это означает, что обработчик события для целевого элемента будет вызываться последним, за ним следует обработчик события для его родительского элемента и так далее. Всплывающие события можно остановить, вызвав метод preventDefault() для объекта события.

<button onClick={handleClick}>Click Me!</button>

function handleClick() {
  // Do something when the button is clicked
}

Когда пользователь нажмет на кнопку, будет вызвана функция handleClick. Затем эту функцию можно использовать для выполнения любого желаемого действия, например, для изменения состояния приложения или отображения сообщения.

Если вы хотите узнать больше о событиях для ReactJS, перейдите по этой официальной ссылке на документацию.



Теперь мы узнали о context API, хуке useReducer и многом другом.

Пришло время разработать мощную систему аутентификации без использования избыточности.

Итак, начнем, ребята 😊…

Сначала нам нужно определить начальное состояние или значение для контекста. Позвольте мне показать вам

const initialState = {
    token: localStorage.getItem("token") ? localStorage.getItem("token") : null,
    isLoading: false,
    message: null,
    error: null,
};

Вы можете объявить начальное состояние в соответствии с вашими требованиями.

Ключевая концепция заключается в том, что этот код определяет начальное состояние Context API. Объект состояния содержит четыре свойства:

  • token: в этом свойстве хранится токен проверки подлинности пользователя. Если пользователь не аутентифицирован, это свойство будет null.
  • isLoading: Это свойство указывает, загружает ли приложение данные в данный момент.
  • message: Это свойство хранит сообщение, которое отображается пользователю.
  • error: это свойство хранит сообщение об ошибке, которое отображается пользователю.

Начальное состояние приложения определяется значениями этих свойств. Например, если пользователь прошел проверку подлинности, свойство token будет установлено на токен проверки подлинности пользователя. Если приложение не загружает данные, для свойства isLoading будет установлено значение false.

Начальное состояние приложения используется для инициализации пользовательского интерфейса приложения. Например, если для свойства token установлено значение, отличное от null, приложение отобразит имя пользователя и изображение профиля. Если для свойства isLoading установлено значение true, приложение отобразит индикатор загрузки.

Второе, что нам нужно для создания экземпляра контекста

const authContext = createContext(initialState);

Этот код создает контекст React с именем AuthContext. Контекст — это способ обмена данными между различными компонентами в приложении React. Функция createContext принимает два аргумента: имя контекста и начальное состояние. Исходное состояние — это данные, которые будут доступны компонентам, использующим контекст, при первом рендеринге.

Вы можете дать любое имя экземпляру

В-третьих, нам нужно создать редуктор для хука useReducer.

const setReducerState = (state = initialState, { type, payload }) => {
    switch (type) {
        case "LOGIN_PENDING":
            return { ...state, isLoading: true }
        case "LOGIN_SUCCESS":
            localStorage.setItem("token", payload.token);
            return {
                ...state,
                isLoading: false,
                token: payload.token,
                message: payload.message
            }
        case "LOGIN_FAILED":
            return { ...state, isLoading: false, error: payload }
        case "LOGOUT":
            localStorage.removeItem("token");
            return { ...state, token: null, message: "Logout successfully !", error: null }
        default: return state;
    }
}

Функция setReducerState — это функция-редуктор, которая используется для обновления состояния приложения. Функция принимает два аргумента:

  • state: Текущее состояние приложения.
  • action: объект, содержащий информацию о событии, вызвавшем обновление состояния. (Тип, полезная нагрузка)

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

  • LOGIN_PENDING: Приложение находится в процессе входа в систему. Состояние обновляется, чтобы показать, что приложение загружается.
  • LOGIN_SUCCESS: пользователь успешно вошел в систему. Состояние обновляется, чтобы показать, что пользователь вошел в систему, а токен хранится в локальном хранилище.
  • LOGIN_FAILED: Пользователю не удалось войти в систему. Состояние обновляется, чтобы показать, что пользователь не вошел в систему, и отображается сообщение об ошибке.
  • LOGOUT: Пользователь вышел из системы. Маркер удаляется из локального хранилища, а состояние обновляется, чтобы показать, что пользователь не вошел в систему.

В-четвертых, нам нужно создать один компонент для управления и обновления контекста в одном месте.

const Authentication = ({
    children
}) => {    
    return (<>
        <authContext.Provider value={{
            /* Values */
        }}>
            {children}
        </authContext.Provider>
    </>)
};
  • Этот код определяет компонент с именем Authentication.
  • Authentication компонент принимает один реквизит с именем children.
  • Компонент Authentication отображает компонент authContext.Provider.
  • Компонент authContext.Provider имеет реквизит value, который представляет собой объект со следующими значениями:
  • Компонент Authentication отображает реквизит children внутри компонента authContext.Provider.
  • Это позволяет компоненту Authentication получить доступ к статусу и данным аутентификации пользователя.

Пришло время отправлять действия

const Authentication = ({
    children
}) => {
    const [values, dispatch] = useReducer(setReducerState, initialState);
    const handleLogin = async (payload) => {
        try {
            dispatch({ type: "LOGIN_PENDING" });
            const response = await fetch({
                url: /* Login URL */,
                method: "post",
                body: payload
            });
            const convertedData = await response.json();
            dispatch({
                type: "LOGIN_SUCCESS",
                payload: {
                    token: convertedData.token,
                    message: convertedData.message,
                }
            });
        } catch (error) {
            dispatch({ type: "LOGIN_FAILED" });
        }
    }
    const handleLogout = async (payload) => {
        dispatch({ type: "LOGOUT" });
    }
    return (<>
        <authContext.Provider value={{
            state: values,
            handleLogin,
            handleLogout
        }}>
            {children}
        </authContext.Provider>
    </>)
};
export default Authentication;

Компонент Authentication отвечает за обработку аутентификации для приложения React. Он использует хук useReducer для управления состоянием аутентификации приложения и предоставляет методы для входа и выхода.

Метод handleLogin отправляет асинхронный запрос к конечной точке /auth/login для входа пользователя в систему. Если запрос выполнен успешно, метод отправляет действие LOGIN_SUCCESS с токеном и сообщением пользователя. Если запрос не выполнен, метод отправляет действие LOGIN_FAILED.

Метод handleLogout отправляет асинхронный запрос к конечной точке /auth/logout для выхода пользователя из системы. Если запрос выполнен успешно, метод отправляет действие LOGOUT.

Компонент Authentication использует authContext для предоставления состояния аутентификации приложения своим дочерним элементам. authContext — это поставщик, который предоставляет следующие свойства:

  • state: состояние аутентификации приложения.
  • handleLogin: Способ входа пользователя.
  • handleLogout: Способ выхода пользователя из системы.

Компонент Authentication следует использовать в качестве корневого компонента приложения React, требующего аутентификации.

Теперь мы можем реализовать контекстный API в корневом компоненте.

import './App.css';
import Authentication from './Authentication';

function App() {
  return (
    <>
      <Authentication>
        <h1>THIS DATA IS RENDERED</h1>
      </Authentication>
    </>
  );
}

export default App;

Приведенный выше код импортирует компонент Authentication из файла ./Authentication и отображает его внутри компонента App. Компонент Authentication отвечает за обработку аутентификации для приложения React. Он использует хук useReducer для управления состоянием аутентификации приложения и предоставляет методы для входа и выхода.

Компонент App визуализирует компонент Authentication и элемент h1 с текстом «ЭТИ ДАННЫЕ ОТОБРАЖЕНЫ». Компонент Authentication будет отображать элемент h1 только в том случае, если пользователь вошел в систему.

Весь код в одном фрагменте кода

import { createContext, useReducer } from "react";

const initialState = {
    token: localStorage.getItem("token") ? localStorage.getItem("token") : null,
    isLoading: false,
    message: null,
    error: null,
};

const authContext = createContext(initialState);

const setReducerState = (state = initialState, { type, payload }) => {
    switch (type) {
        case "LOGIN_PENDING":
            return { ...state, isLoading: true }
        case "LOGIN_SUCCESS":
            localStorage.setItem("token", payload.token);
            return {
                ...state,
                isLoading: false,
                token: payload.token,
                message: payload.message
            }
        case "LOGIN_FAILED":
            return { ...state, isLoading: false, error: payload }
        case "LOGOUT":
            localStorage.removeItem("token");
            return { ...state, token: null, message: "Logout successfully !", error: null }
        default: return state;
    }
}

const Authentication = ({
    children
}) => {
    const [values, dispatch] = useReducer(setReducerState, initialState);
    const handleLogin = async (payload) => {
        try {
            dispatch({ type: "LOGIN_PENDING" });
            const response = await fetch({
                url: "http://192.168.100.86:3000/auth/login",
                method: "post",
                body: payload
            });
            const convertedData = await response.json();
            dispatch({
                type: "LOGIN_SUCCESS",
                payload: {
                    token: convertedData.token,
                    message: convertedData.message,
                }
            });
        } catch (error) {
            dispatch({ type: "LOGIN_FAILED" });
        }
    }
    const handleLogout = async (payload) => {
        dispatch({ type: "LOGOUT" });
    }
    return (<>
        <authContext.Provider value={{
            state: values,
            handleLogin,
            handleLogout
        }}>
            {children}
        </authContext.Provider>
    </>)
};
export default Authentication;

Надеюсь, это поможет вам 😇

Ресурсы для изучения ReactJS







Большое спасибо, ребята 🙂, продолжайте делиться 🙃