Полная разработка

Строительные блоки TypeScript: подробное руководство по универсальной сериализации JSON в React и Angular

Изучите создание универсального сериализатора JSON с помощью TypeScript с реальными приложениями в React и Angular: четкое и краткое руководство как для начинающих, так и для опытных программистов.

Шаг первый: введение в JSON и его роль в обмене данными

Привет, любители техники! Я рад вместе с вами начать это путешествие в сериализацию TypeScript и JSON.

JSON: сердце обмена данными

Вы когда-нибудь задумывались, как различные части программного приложения взаимодействуют друг с другом? Они часто делают это, используя JSON (обозначение объектов JavaScript). JSON — это простой и удобный для чтения формат данных, который различные части программного обеспечения используют для общения друг с другом.

Когда мы создаем веб-приложения, мы часто отправляем, получаем и работаем с данными JSON. Он легкий и простой в использовании как для людей, так и для компьютеров. Он работает со многими разными языками программирования, от JavaScript до Python, Ruby и C#, и, конечно же, TypeScript, о котором мы сегодня поговорим.

TypeScript и JSON: зачем нам хороший сериализатор

TypeScript — это версия JavaScript, в которую добавлены принципы объектно-ориентированного программирования. Это делает наш код более безопасным и простым в управлении, что особенно полезно, когда мы работаем с большими проектами. Если вы раньше работали с TypeScript, то знаете, что нам часто приходится иметь дело с данными JSON.

Но работа с данными может быть сложной. У вас когда-нибудь возникала проблема из-за того, что полученные данные были не в том формате, который вы ожидали? Или, может быть, вы пытались получить доступ к несуществующему полю в ваших данных JSON, и ваше приложение разбилось?

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

В следующих разделах мы узнаем, как создать сериализатор JSON в TypeScript и даже применим эту концепцию в двух самых популярных интерфейсных фреймворках — React и Angular.

Теперь давайте перейдем к пониманию основ сериализации JSON. Держать крепко!

Шаг второй: основы сериализации JSON

Итак, давайте продолжим наше путешествие, изучая основы сериализации JSON.

Распаковка сериализации JSON

Итак, что же такое сериализация JSON? Проще говоря, это процесс преобразования более сложных данных в формат, который можно легко хранить или отправлять. Когда мы сериализуем данные, мы конвертируем их в строковый формат (в нашем случае JSON), который можно легко передавать по сети или сохранять для последующего использования.

Вы когда-нибудь играли с кубиками LEGO? Думайте о сериализации как о том, чтобы упаковать готовый замок LEGO в коробку для хранения. Когда вы будете готовы снова играть, вы просто вытаскиваете кусочки (или десериализуете их) и снова строите свой замок.

Необходимость сериализации JSON

Теперь, почему это важно? Представьте, что вы создаете погодное приложение. Это приложение собирает данные о погоде с различных метеостанций по всему миру и отображает их пользователю. Эти метеостанции отправляют данные в различных форматах, некоторые в градусах Фаренгейта, некоторые в градусах Цельсия, некоторые могут даже использовать кельвины!

Здесь на помощь приходит сериализация JSON. Она действует как универсальный транслятор, преобразуя все различные форматы в один общий формат (JSON), понятный вашему приложению. Это упрощает обработку данных и делает ваше приложение более надежным.

Механизм сериализации JSON

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

Например, предположим, что у вас есть простой объект JavaScript, представляющий книгу, например:

let book = {
  title: "The Great Gatsby",
  author: "F. Scott Fitzgerald",
  year: 1925
};

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

"{\"title\":\"The Great Gatsby\",\"author\":\"F. Scott Fitzgerald\",\"year\":1925}"

Прелесть этого в том, что эту строку JSON теперь можно легко сохранить в базе данных, отправить по сети или использовать в другой части вашего приложения. Когда вам нужно снова работать с данными, вы просто десериализуете их обратно в объект JavaScript.

Итак, вы готовы погрузиться глубже и приступить к созданию универсального сериализатора JSON в TypeScript? Пойдем!

Шаг третий: написание универсального сериализатора JSON на TypeScript

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

Сериализация JSON и TypeScript: основы

Первое, что нам нужно понять, это то, что мы подразумеваем под «универсальным» сериализатором JSON. В TypeScript «универсальный» означает, что он может работать со многими типами данных. Таким образом, универсальный сериализатор JSON — это инструмент, который может преобразовать любую структуру данных в строку JSON и наоборот.

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

Теперь давайте начнем писать наш сериализатор.

1. Начните с простого

Начнем с простого случая. Мы напишем функцию, которая берет объект TypeScript и преобразует его в строку JSON.

function serialize<T>(data: T): string {
  return JSON.stringify(data);
}

Здесь <T> является заполнителем для любого типа. Это может быть строка, число, объект или любой другой тип в TypeScript. Аргумент data — это наш объект TypeScript, а JSON.stringify(data) преобразует его в строку JSON.

2. Сделайте это двунаправленным

Теперь, когда мы можем преобразовывать объекты TypeScript в JSON, давайте добавим возможность сделать обратное. Мы напишем еще одну функцию, которая берет строку JSON и преобразует ее обратно в объект TypeScript.

function deserialize<T>(json: string): T {
  return JSON.parse(json) as T;
}

Опять же, <T> является заполнителем для любого типа. Аргумент json представляет собой строку JSON, а JSON.parse(json) преобразует ее обратно в объект TypeScript.

3. Добавьте обработку ошибок

Наш сериализатор работает, но что произойдет, если что-то пойдет не так? Что, если мы попытаемся десериализовать строку, которая не является допустимым JSON? Прямо сейчас наше приложение вылетит. Чтобы предотвратить это, мы добавим некоторую обработку ошибок.

function deserialize<T>(json: string): T {
  try {
    return JSON.parse(json) as T;
  } catch (error) {
    console.error('Failed to parse JSON:', error);
    return null;
  }
}

Теперь, если JSON.parse(json) выдает ошибку, мы ее поймаем и запишем в консоль. Затем мы вернем null, чтобы указать, что десериализация не удалась.

Вот оно! Мы создали простой, но мощный универсальный сериализатор JSON на TypeScript. В следующих разделах мы узнаем, как его улучшить и протестировать.

Вот реализация предыдущего примера JSON в качестве класса TypeScript, который я буду использовать в следующих случаях использования.

class BookData {
  title: string;
  author: string;
  year: number;

  constructor(title: string, author: string, year: number) {
    this.title = title;
    this.author = author;
    this.year = year;
  }
}

Расширение концепции: применение сериализации JSON в React

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

Создание пользовательского хука для сериализации

Мы все любим React за его компонентный подход и многократно используемую логику с отслеживанием состояния. И это именно то, куда мы сейчас направляемся. Мы воспользуемся мощью хуков в React, чтобы создать собственный useSerializer<T>(). Этот пользовательский хук вернет две функции: serialize и deserialize, обе адаптированы для работы с нашим типом данных T.

Приступаем к кодированию.

import { useCallback } from 'react';

function useSerializer<T>() {
  const serialize = useCallback((data: T): string => {
    return JSON.stringify(data);
  }, []);

  const deserialize = useCallback((json: string): T | null => {
    try {
      return JSON.parse(json) as T;
    } catch (error) {
      console.error('Failed to parse JSON:', error);
      return null;
    }
  }, []);

  return { serialize, deserialize };
}

В этом хуке useCallback возвращает запомненную версию функций serialize и deserialize. По сути, это означает, что функции не меняются при повторном рендеринге, если не меняются их зависимости. Здесь у нас нет никаких зависимостей, но использование useCallback гарантирует, что наши компоненты будут работать хорошо и не будут перерисовываться без необходимости.

💡Что, если бы вы могли повторно использовать обработчик useSerializer во всех своих проектах? Вы можете сделать это, используя цепочку инструментов с открытым исходным кодом, например Bit, и простой файл bit import your.username/useSerializer.

Узнайте больше здесь:



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

Теперь давайте посмотрим на наш пользовательский хук в действии в компоненте React:

import React, { useState, useEffect } from 'react';
import useSerializer from './useSerializer';

function ExampleSerializerComponent() {
  const { serialize, deserialize } = useSerializer<MyData>();
  const [data, setData] = useState<BookData | null>(null);

  useEffect(() => {
    async function fetchData() {
      const response = await fetch('/api/data');
      const json = await response.text();
      const data = deserialize(json);
      setData(data);
    }

    fetchData();
  }, [deserialize]);

  const handleSave = () => {
    const json = serialize(data);
    localStorage.setItem('bookData', json);
  };

  // Render the component
}

В этом компоненте при первом рендеринге ExampleSerializerComponent извлекает данные из API, десериализует ответ JSON в объект BookData и сохраняет его в своем состоянии. Когда пользователь инициирует операцию сохранения, он сериализует данные обратно в JSON и сохраняет их в localStorage.

Расширение концепции: применение сериализации JSON в Angular

После создания универсального сериализатора JSON в TypeScript и расширения его до React пришло время посмотреть, как мы можем применить ту же концепцию к Angular.

Создание универсальной службы сериализатора

В Angular мы обычно инкапсулируем нашу общую логику в сервисы. Итак, для наших задач сериализации мы создадим SerializerService, используя сервисную структуру Angular.

Вот как вы можете определить эту услугу:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class SerializerService {
  serialize<T>(data: T): string {
    return JSON.stringify(data);
  }

  deserialize<T>(json: string): T | null {
    try {
      return JSON.parse(json) as T;
    } catch (error) {
      console.error('Failed to parse JSON:', error);
      return null;
    }
  }
}

Этот SerializerService предоставляет два метода, serialize и deserialize, которые выполняют те же задачи, что и в наших предыдущих примерах.

Использование SerializerService в компоненте Angular

Теперь давайте посмотрим, как мы можем использовать этот сервис в компоненте Angular:

import { Component, OnInit } from '@angular/core';
import { SerializerService } from './serializer.service';

@Component({
  selector: 'app-exampleserializer-component',
  templateUrl: './exampleserializer.component.html',
  styleUrls: ['./exampleserializer.component.css'],
})
export class ExampleSerializerComponent implements OnInit {
  data: BookData | null = null;

  constructor(private serializerService: SerializerService) {}

  ngOnInit() {
    this.fetchData();
  }

  async fetchData() {
    const response = await fetch('/api/data');
    const json = await response.text();
    this.data = this.serializerService.deserialize<BookData>(json);
  }

  handleSave() {
    const json = this.serializerService.serialize<MyData>(this.data);
    localStorage.setItem('bookData', json);
  }
}

Здесь ExampleSerializerComponent извлекает данные из API при его инициализации, использует метод deserialize из SerializerService для преобразования ответа JSON в объект BookData и сохраняет его в своем свойстве data. Когда пользователь инициирует операцию сохранения, он использует метод serialize для преобразования данных обратно в строку JSON и сохраняет их в localStorage.

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

Обеспечение эффективности: тестирование и улучшение сериализатора JSON

Итак, на этом этапе мы рассмотрели концепцию сериализации JSON, увидели, как создать универсальный сериализатор в TypeScript, и даже расширили эту концепцию до React и Angular. Теперь пришло время убедиться, что то, что мы создали, работает так, как ожидалось.

Модульное тестирование вашего сериализатора

Мы все согласны с важностью тестирования, поэтому давайте удостоверимся, что наш сериализатор работает правильно. Давайте рассмотрим Jest для React и Jasmine для Angular в качестве наших инструментов тестирования, но не стесняйтесь использовать любой инструмент, который вам удобен.

  • Реакция
import { renderHook, act } from '@testing-library/react-hooks';
import useSerializer from './useSerializer';

describe('useSerializer', () => {
  it('should serialize and deserialize correctly', () => {
    const { result } = renderHook(() => useSerializer<{ title: string, author: string, year: number }>());
    const { serialize, deserialize } = result.current;

    const book = { title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: 1925 };
    let json;
    act(() => {
      json = serialize(book);
    });
    expect(json).toBe('{"title":"The Great Gatsby","author":"F. Scott Fitzgerald","year":1925}');

    let parsedBook;
    act(() => {
      parsedBook = deserialize(json);
    });
    expect(parsedBook).toEqual(book);
  });
});
  • Угловой
import { SerializerService } from './serializer.service';

describe('SerializerService', () => {
  let service: SerializerService;

  beforeEach(() => {
    service = new SerializerService();
  });

  it('should serialize and deserialize correctly', () => {
    const book = {
      title: "The Great Gatsby",
      author: "F. Scott Fitzgerald",
      year: 1925
    };
    
    const json = service.serialize(book);
    expect(json).toBe('{"title":"The Great Gatsby","author":"F. Scott Fitzgerald","year":1925}');

    const parsedBook = service.deserialize<{ title: string, author: string, year: number }>(json);
    expect(parsedBook).toEqual(book);
  });
});

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

💡 Если бы вы использовали такую ​​платформу, как Bit, для публикации, совместного использования и повторного использования ваших компонентов React или Angular, с каждым публикуемым вами компонентом были бы связаны модульные тесты. С помощью «функции композиций в Bit вы можете автоматически создавать *.spec.* и распознавать файлы *.test.*, а каждый компонент, который вы публикуете и версии на Bit, будет включать в себя тесты в качестве основы, что дает вам уверенность в вашем коде.

Узнайте больше здесь:



Оптимизация вашего кода

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

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

Вот как можно реализовать простую мемоизацию для функции serialize, используя Map для хранения ранее сериализованных объектов:

class MemoizingSerializer<T> {
  private cache = new Map<T, string>();

  serialize(data: T): string {
    if (this.cache.has(data)) {
      return this.cache.get(data)!;
    }

    const json = JSON.stringify(data);
    this.cache.set(data, json);
    return json;
  }

  // ...
}

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

Подведение итогов: дополнительная литература по JavaScript

Мы вместе прошли через увлекательный мир сериализации JSON в TypeScript, применили наши знания к React и Angular и даже научились тестировать и оптимизировать наши сериализаторы.

Куда пойти отсюда

Помните, что обучение — это процесс на всю жизнь, а мир разработки программного обеспечения постоянно развивается. Сериализация JSON — это лишь небольшая часть более широкой экосистемы JavaScript. Я призываю вас глубже изучить JavaScript, TypeScript и различные фреймворки, такие как React и Angular.

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







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

Спасибо, что присоединились ко мне

Завершая это путешествие, я хочу выразить вам глубочайшую благодарность, дорогой читатель, за то, что вы потратили свое время на обучение вместе со мной.

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

💡 Небольшое предупреждение: если вы решите купить эту книгу, вы поддержите мою работу без каких-либо дополнительных затрат для вас. Это беспроигрышный вариант — вы можете погрузиться в захватывающее чтение, а я буду продолжать создавать контент, который вам нравится. Ваша поддержка моей работы очень ценна!

Кроме того, если вы нашли этот материал ценным, не забудьте подписаться на меня, чтобы получить более подробный контент, подобный этому! 😄💻 #Средний #Следуй за мной

Создавайте приложения React с повторно используемыми компонентами, как Lego

Инструмент с открытым исходным кодом Bit помогает более чем 250 000 разработчиков создавать приложения с компонентами.

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

Подробнее

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

Микро-интерфейсы

Система дизайна

Совместное использование кода и повторное использование

Монорепо

Узнать больше: