Diversity w polskim IT
Mohammad Faisal
Mohammad FaisalSenior Software Engineer @ Advanced Mobility Analytics

7 bibliotek do tworzenia błyskawicznych aplikacji React

Poznaj 7 bibliotek React, które mogą poprawić jakość Twojego kodu i jednocześnie zwiększyć jego wydajność.
16.09.20215 min
7 bibliotek do tworzenia błyskawicznych aplikacji React

ReactJS domyślnie jest bardzo wydajny, ale od czasu do czasu pojawia się szansa, aby uczynić go jeszcze lepszym. Niesamowita społeczność Reacta wymyśliła kilka fantastycznych bibliotek, które przedstawiam w tym artykule.

Opowiem o 7 takich bibliotekach, które mogą poprawić jakość Twojego kodu i jednocześnie zwiększyć jego wydajność. Zaczynajmy!

React Query


React Query brakująca biblioteka do zarządzania stanem w React.  W dokumentacji możemy przeczytać: „Wywołuj, przechowuj i aktualizuj dane w swoich aplikacjach React bez dotykania jakiegokolwiek 'stanu globalnego'”. 

Tak. To jest dokładnie to, co robi. Pomaga nam to w bezproblemowym zarządzaniu stanem. Może to zredukować konieczność używania innych bibliotek, takich jak Redux

Zalety

  • Automatyczne cache’owanie
  • Automatyczna aktualizacja danych w tle
  • Znacząca redukcja kodu


Przed React Query

Poniżej znajduje się przykładowy niestandardowy hook do pobierania danych. Nie obsługuje nawet cache’owania.

const useFetch = (url) => {
  const [data, setData] = useState();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);
 
  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);
      try {
        const result = await fetch(url);
        setData(result.data);
      } catch (error) {
        setError(error);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [url]);
  
  return {data , isLoading , isError}
}


Po React Query

Poniżej pokazuję kod, jeśli chcemy użyć React Query. Zobacz, jaki jest krótki.

import { useQuery } from 'react-query'

const { isLoading, error, data } = useQuery('repoData', () =>
    fetch(url).then(res =>res.json()
  )
)


Zobaczcie również, jak wiele nieistotnych szczegółów mogliśmy pominąć

React Hook Form

React Hook Form jest nowoczesną biblioteką obsługi formularzy, która może przenieść wydajność Twojego formularza na zupełnie nowy poziom.

Zalety

  • Redukcja kodu
  • Redukcja niepotrzebnego renderowania
  • Łatwa integracja z nowoczesnymi bibliotekami UI


Poniżej znajduje się przykład, który demonstruje, jak React Hook Form może poprawić jakość kodu.

Bez React Hook Form

Oto przykład ręcznie zbudowanego formularza logowania

function LoginForm() {
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log({email, password});
  }
  
  return (
    <form onSubmit={handleSubmit}>
    
      <input
        type="email"
        id="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      
      <input
        type="password"
        id="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      
    </form>
  );
}


Z React Form

Oto ten sam przykład z zastosowaniem React Hook Form.

function LoginForm() {
  const { register, handleSubmit } = useForm();
  
  const onSubmit = data => console.log(data);
   
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("email")} />
      <input {...register("password")} />
      <input type="submit" />
    </form>
  );
}


Jest bardzo czysty i jednocześnie wydajny. Wypróbuj sam.

React Window

React Window jest używany do renderowania długich list. Wyobraź sobie, że masz listę 1 000 pozycji. Tylko dziesięć jest widocznych w danym momencie, ale Twój kod próbuje renderować wszystkie 1000 elementów w tym samym czasie.

Może to spowodować, że aplikacja zacznie się zacinać. Jest to bardzo popularna biblioteka i obowiązkowe narzędzie w Twoim arsenale.

Ręczne renderowanie 1 000 elementów

import React, {useEffect, useState} from 'react';

const names = [] // 1000 names

export const LongList = () => {

    return <div> 
      {names.map(name => <div> Name is: {name} </div>)} 
    <div/>
}


Ten kod renderuje 1000 elementów na raz, choć na ekranie widać najwyżej 10-20 elementów.

Użycie React Window

A teraz zastosujmy React Window

import { FixedSizeList as List } from 'react-window';
 
const Row = ({ index, style }) => <div style={style}> Name is {names[index]}</div>
 
const LongList = () => (
  <List
    height={150}
    itemCount={1000}
    itemSize={35}
    width={300}
  >
    {Row}
  </List>
);


Ten kod renderuje tylko to, co widać na ekranie. Może to być nieco przerażające na początku, ale konieczne, jeśli posiadasz długą listę do zrenderowania.

React LazyLoad

Lazy loading jest techniką używaną do wczytywania tylko tych elementów, które są potrzebne w danym momencie. W ten sposób poprawia wydajność, nie nadużywając zasobów.

React LazyLoad jest biblioteką stworzoną specjalnie do tego celu. Po prostu owijasz swój komponent, a biblioteka zajmuje się resztą.

Zalety

  • Lepsza wydajność
  • Obsługa renderowania po stronie serwera


Bez LazyLoad

Oto przykład, w którym przesyłamy pięć obrazów ręcznie.

import React from 'react';

const ImageList = () => {
  
  return <div>
    <img src ='image1.png' />
    <img src ='image2.png' />
    <img src ='image3.png' />
    <img src ='image4.png' />
    <img src ='image5.png' />
  </div>
}


Z LazyLoad

Oto ten sam przykład z zastosowaniem komponentu LazyLoad.

import React from 'react';
import LazyLoad from 'react-lazyload';


const ImageList = () => {
  
  return <div>
    <LazyLoad> <img src ='image1.png' /> <LazyLoad>
    <LazyLoad> <img src ='image2.png' /> <LazyLoad>
    <LazyLoad> <img src ='image3.png' /> <LazyLoad>
    <LazyLoad> <img src ='image4.png' /> <LazyLoad>
    <LazyLoad> <img src ='image5.png' /> <LazyLoad>
  </div>
}

Why Did You Render

Niepotrzebne renderowanie może zaszkodzić wydajności Twoich aplikacji w React, ale czasami robimy to nieświadomie.

Ten świetny pakiet Why Did You Render pomaga nam znaleźć problemy z wydajnością i je rozwiązywać. Wystarczy włączyć go w dowolnym komponencie, a powie Ci dokładnie, dlaczego renderuje.

Poniżej znajduje się komponent z problemami renderowania.

import React, {useState} from 'react'

const WhyDidYouRenderDemo = () => {
    console.log('render')
    
    const [user , setUser] = useState({})
    const updateUser = () => setUser({name: 'faisal'})

    return <>
        <div > User is : {user.name}</div>
        <button onClick={updateUser}> Update </button>
    </>
}

export default WhyDidYouRenderDemo


Po włączeniu biblioteka ta wyrzuci do konsoli:


Z powyższego możemy zobaczyć, że aktualizujemy obiekt z tą samą wartością, co jest złe dla wydajności.

Reselect

Jeśli używasz Redux to to uratuje Ci życie. Wiemy, że reduktory Reduxa mogą przechowywać wiele danych, a jeśli podasz kompletny store do dowolnego komponentu, spowoduje to, że będzie on renderowany za każdym razem, gdy cokolwiek w tym storze się zaktualizuje.

Reselect rozwiązuje ten problem poprzez zapamiętywanie wartości i przekazywanie tylko tego, co niezbędne.

Zalety (z dokumentacji)

  • Selektory mogą obliczać dane pochodne, pozwalając Reduxowi na przechowywanie minimalnego możliwego obiektu stanu.
  • Selektory są wydajne. Selektor nie jest obliczany ponownie, chyba że zmieni się jeden z jego argumentów.
  • Selektory można komponować. Mogą być używane jako wejście do innych selektorów.


Przykład

Poniżej znajduje się przykład pobrania wartości z wnętrza magazynu i zmodyfikowania ich w selektorze.

import { createSelector } from 'reselect'

const shopItemsSelector = state => state.shop.items

const subtotalSelector = createSelector(
  shopItemsSelector,
  items => items.reduce((subtotal, item) => subtotal + item.value, 0)
)

const exampleState = {
  shop: {
    items: [
      { name: 'apple', value: 1.20 },
      { name: 'orange', value: 0.95 },
    ]
  }
}

Deep Equal

Deep Equal jest popularna biblioteką, która może być używana do porównywania. Jest ona bardzo przydatna. Koniec końców w JavaScript, chociaż dwa obiekty mogą mieć te same wartości, są uważane za różne, ponieważ wskazują na różne lokacje w pamięci.

Dlatego też widzimy następujący wynik.

const user1 = {
    name:'faisal'
}
const user2 ={
    name:'faisal'
}

const normalEqual = user1 === user2 // false


A jeśli musisz sprawdzić równość (dla zapamiętywania), staje się to kosztowną (i złożoną) operacją.

Jeśli użyjemy Deep Equal, poprawia to wydajność o 46 razy. Poniżej znajduje się przykład pokazujący, jak możemy to zastosować.

var equal = require('deep-equal');

const user1 = {
    name:'faisal'
}
const user2 ={
    name:'faisal'
}

const deepEqual = equal(user1 , user2); // true -> exactly what we wanted!


Proszę bardzo. Są to jedne z najważniejszych bibliotek, których możesz korzystać, aby zmaksymalizować wydajność swojej aplikacji React.

Jeśli chciałbyś jeszcze o jakiejś wspomnieć, zostaw komentarz. Dobrego dnia!



Oryginał tekstu w języku angielskim przeczytasz tutaj.

<p>Loading...</p>