Chcesz podnieść swoje umiejętności programowania w React? Zbuduj własną wersję Hacker News za pomocą tego przewodnika.

Hacker News to popularna witryna wśród przedsiębiorców i programistów. Zawiera treści skoncentrowane na informatyce i przedsiębiorczości.

Prosty układ Hacker News może odpowiadać niektórym osobom. Jeśli jednak potrzebujesz bardziej atrakcyjnej i spersonalizowanej wersji, możesz skorzystać z pomocnych interfejsów API, aby stworzyć własne, dostosowane do potrzeb Hacker News. Ponadto zbudowanie klona Hacker News może pomóc w utrwaleniu umiejętności React.

Konfigurowanie serwera projektowego i programistycznego

Kod użyty w tym projekcie jest dostępny w formacie Repozytorium GitHub i jest darmowy do użytku na licencji MIT.

W celu stylizacji skopiuj zawartość pliku indeks.css plik z repozytorium i wklej go do własnego indeks.css plik. Jeśli chcesz zobaczyć wersję tego projektu na żywo, możesz to sprawdzić próbny.

Pakiety potrzebne do tego projektu obejmują:

  • React Router do obsługi routingu w Aplikacja jednostronicowa (SPA).
  • instagram viewer
  • HTMLReactParser do analizowania kodu HTML zwróconego przez Interfejs programowania aplikacji (API).
  • MomentJS do obsługi dat zwracanych przez API.

Otwórz terminal i uruchom:

przędza tworzy vite

Możesz także skorzystać z tzw Menedżer pakietów węzłów (NPM) jeśli wolisz to od przędzy. Powyższe polecenie powinno używać narzędzia do budowania Vite do rusztowania podstawowego projektu. Nazwij swój projekt i po wyświetleniu monitu o ramy wybierz Reagować i ustaw wariant na JavaScript.

Teraz płyta CD do folderu projektu i zainstaluj wspomniane wcześniej pakiety, uruchamiając następujące polecenia w terminalu:

przędza dodaje html-react-parser
przędza dodaj adres-router-dom
przędza dodać chwilę
rozwinięcie przędzy

Po zainstalowaniu wszystkich pakietów i uruchomieniu serwera deweloperskiego otwórz projekt w dowolnym edytorze kodu i utwórz trzy foldery w źródło folder, a mianowicie: składniki, haki, I strony.

w składniki folder, dodaj dwa pliki Komentarze.jsx I Navbar.jsx. w haki folder, dodaj jeden plik useFetch.jsx. Następnie w strony folder, dodaj dwa pliki ListPage.jsx I PostPage.jsx.

Usuń Aplikacja.css plik i zastąp zawartość pliku main.jsx plik z następującą treścią:

import Reagować z'reagować'
import { Router przeglądarki } z„React-router-dom”
import ReactDOM z„reaguj/klient”
import Aplikacja z„./Aplikacja.jsx”
import'./index.css'

ReactDOM.createRoot(dokument.getElementById('źródło')).renderowanie(



</BrowserRouter>
</React.StrictMode>,
)

w Aplikacja.jsx plik, usuń cały kod wzorcowy i zmodyfikuj plik tak, aby pozostał tylko komponent funkcjonalny:

funkcjonowaćAplikacja() {
powrót (
<>
</>
)
}

eksportdomyślny Aplikacja

Zaimportuj niezbędne moduły:

import { Trasy, Trasa } z„React-router-dom”
import Strona listy z„./pages/ListPage”
import Pasek nawigacyjny z„./komponenty/pasek nawigacyjny”
import Strona pocztowa z„./strony/strona pocztowa”

We fragmencie React dodaj Trasy komponenty z trzema Trasa komponenty potomne ze ścieżkami: /, /:type, I /item/:id odpowiednio.


'/'
element={<> <Pasek nawigacyjny /><Strona listy /></>}>
</Route>
'/:typ'
element={<> <Pasek nawigacyjny /><Strona listy /></>}>
</Route>
'/pozycja/:identyfikator'
element={}>
</Route>
</Routes>

Tworzenie niestandardowego haka useFetch

Ten projekt używa dwóch interfejsów API. Pierwsze API odpowiada za pobranie listy postów w danej kategorii (typ), natomiast drugim API jest Algolia API, które odpowiada za pobranie konkretnego posta i jego uwagi.

Otworzyć useFetch.jsx plik, zdefiniuj hak jako domyślny eksport i zaimportuj plik stan użycia I UżyjEfekt haki.

import { stan użycia, efekt użycia } z"reagować";
eksportdomyślnyfunkcjonowaćużyj Pobierz(typ, ident) {

}

Zdefiniuj trzy zmienne stanu, a mianowicie: dane, błąd, I Ładowanie, z ich odpowiednimi funkcjami ustawiającymi.

konst [dane, ustawdane] = useState();
konst [błąd, setError] = useState(FAŁSZ);
konst [ładowanie, ładowanie set] = useState(PRAWDA);

Następnie dodaj A UżyjEfekt hook z zależnościami: ID I typ.

użyjEfekt(() => {
}, [Typ identyfikatora])

Następnie w funkcji wywołania zwrotnego dodaj funkcję pobieranie danych() aby pobrać dane z odpowiednich interfejsów API. Jeśli przekazany parametr to typ, użyj pierwszego interfejsu API. W przeciwnym razie użyj drugiego interfejsu API.

asynchronicznyfunkcjonowaćpobierz dane() {
pozwalać odpowiedź, adres URL, parametr;
Jeśli (typ) {
adres URL = " https://node-hnapi.herokuapp.com/";
parametr = type.toLowerCase();
}
w przeciwnym razieJeśli (ID) {
adres URL = " https://hn.algolia.com/api/v1/items/";
parametr = id.toLowerCase();
}
próbować {
odpowiedź = czekać na aportować(`${url}${parametr}`);
} złapać (błąd) {
setBłąd(PRAWDA);
}

Jeśli (odpowiedź) Jeśli (odpowiedź.status !== 200) {
setBłąd(PRAWDA);
} w przeciwnym razie {
pozwalać dane = czekać na odpowiedź.json();
ładowanie zestawu(FAŁSZ);
ustaw dane (dane);
}
}
pobierzDane();

Na koniec zwróć Ładowanie, błąd, I dane zmienne stanu jako obiekt.

powrót { ładowanie, błąd, dane};

Renderowanie listy postów w zależności od żądanej kategorii

Za każdym razem, gdy użytkownik przechodzi do / Lub /:type, React powinien renderować plik Strona listy część. Aby zaimplementować tę funkcjonalność, najpierw zaimportuj niezbędne moduły:

import { useNavigate, useParams } z„React-router-dom”;
import użyj Pobierz z„../hooks/useFetch”;

Następnie zdefiniuj komponent funkcjonalny, a następnie przypisz parametr dynamiczny, typ do typ zmienny. Jeśli parametr dynamiczny nie jest dostępny, ustaw typ zmienna do Aktualności. Następnie zadzwoń do tel użyj Pobierz hak.

eksportdomyślnyfunkcjonowaćStrona listy() {
pozwalać { typ } = useParams();
konst nawiguj = użyjNawiguj();
Jeśli (!typ) typ = "Aktualności";
konst { ładowanie, błąd, dane} = useFetch (typ, zero);
}

Następnie zwróć odpowiedni kod JSX w zależności od tego, który z nich Ładowanie, błąd, Lub dane zmienne jest prawdą.

Jeśli (błąd) {
powrót<dz>Coś poszło nie tak!dz>
}

Jeśli (Ładowanie) {
powrót<dz>Ładowaniedz>
}

Jeśli (dane) {
dokument.tytuł = type.toUpperCase();
powrót<dz>

„typ listy”>{typ}</div>
{data.map(przedmiot =>
"przedmiot">
"Nazwa przedmiotu"
onClick={() => nawigacja (`/pozycja/${item.id}`)}>
{Nazwa przedmiotu}
</div>
{item.domena &&
„link do przedmiotu”
onClick={() => otwórz(`${item.url}`)}>
({element.domena})</span>}
</div>)}
</div>
</div>
}

Tworzenie komponentu PostPage

Najpierw zaimportuj odpowiednie moduły i komponenty, a następnie zdefiniuj domyślny komponent funkcjonalny, przypisz ID dynamiczny parametr do ID zmienna i wywołaj użyj Pobierz hak. Upewnij się, że zdestrukturyzowałeś odpowiedź.

import { Łącze, użyj parametrów } z„React-router-dom”;
import analizować z'html-react-parser';
import za chwilę z"za chwilę";
import Uwagi z„../komponenty/Komentarze”;
import użyj Pobierz z„../hooks/useFetch”;

eksportdomyślnyfunkcjonowaćStrona pocztowa() {
konst { id } = useParams();
konst { ładowanie, błąd, dane } = useFetch(zero, ID);
}

I tak jak z Strona listy komponent, wyrenderuj odpowiedni JSX na podstawie stanu następujących zmiennych: Ładowanie, błąd, I dane.

Jeśli (błąd) {
powrót<dz>Coś poszło nie tak!dz>
}

Jeśli (Ładowanie) {
powrót<dz>Ładowaniedz>
}

Jeśli (dane) {
dokument.tytuł=dane.tytuł;
powrót<dz>

„tytuł postu”>{data.title}</div>
„post-metadane”>
{data.url &&
nazwa klasy=„post-link”>Odwiedź stronę internetową</Link>}
„postautor”>{dane.autor}</span>
„po czasie”>
{moment (data.created_at).fromNow()}
</span>
</div>
{data.text &&
„post-tekst”>
{parse (data.text)}</div>}
"Dodaj Komentarze">
„etykieta komentarzy”>Komentarze</div>

</div>
</div>
}

Importuj analizować moduł i za chwilę moduł. Zdefiniuj domyślny komponent funkcjonalny Uwagi to bierze w komentarzeDane array jako rekwizyt, przechodzi przez tablice i renderuje a Węzeł składnik dla każdego elementu.

import analizować z'html-react-parser';
import za chwilę z"za chwilę";

eksportdomyślnyfunkcjonowaćUwagi({ komentarzeDane }) {
powrót<>
{commentsData.map(komentarzDane =><WęzełkomentarzDane={dane komentarza}klucz={commentData.id}
/>)}
</>
}

Następnie zdefiniuj Węzeł element funkcjonalny tuż pod Uwagi część. The Węzeł komponent renderuje komentarz, metadane i odpowiedzi na każdy komentarz (jeśli istnieje) przez rekurencyjne renderowanie samego siebie.

funkcjonowaćWęzeł({ dane komentarza }) {
powrót<dzNazwa klasy="komentarz">
{
komentarzDane.tekst &&
<>
„metadane komentarzy”>
{commentData.author}</span>

{moment (commentData.created_at).fromNow()}
</span>
</div>
„tekst komentarza”
>
{parse (commentData.text)}</div>
</>
}
„odpowiedzi na komentarze”
>
{(commentData.children) &&
komentarzDane.dzieci.map(dziecko =>
)}
</div>
</div>
}

W powyższym bloku kodu analizować jest odpowiedzialny za parsowanie przechowywanego w nim kodu HTML komentarzDane.tekst, chwila za chwilę odpowiada za parsowanie czasu komentarza i zwracanie czasu względnego za pomocą metody od teraz() metoda.

Tworzenie komponentu paska nawigacyjnego

Otworzyć Navbar.jsx zarchiwizuj i zaimportuj plik NavLink moduł z reaguj-router-dom moduł. Na koniec zdefiniuj komponent funkcjonalny i zwróć element nadrzędny nawigacja element z piątką NavLink elementy wskazujące na odpowiednie kategorie (lub typy).

import { NavLink } z„React-router-dom”

eksportdomyślnyfunkcjonowaćPasek nawigacyjny() {
powrót<nawigacja>
"/Aktualności">Dom</NavLink>
"/to, co najlepsze">Najlepszy</NavLink>
"/pokazywać">Pokaż</NavLink>
"/zapytać">Zapytaj</NavLink>
"/Oferty pracy">Praca</NavLink>
</nav>
}

Gratulacje! Właśnie zbudowałeś własnego klienta front-end dla Hacker News.

Ugruntuj swoje umiejętności reagowania, budując aplikację Clone

Zbudowanie klona Hacker News za pomocą React może pomóc w utrwaleniu umiejętności React i zapewnić praktyczną aplikację jednostronicową do pracy. Istnieje wiele sposobów, dzięki którym możesz posunąć się dalej. Na przykład możesz dodać do aplikacji możliwość wyszukiwania postów i użytkowników.

Zamiast próbować zbudować własny router od zera, lepiej skorzystać z narzędzia stworzonego przez profesjonalistów, którzy są zaangażowani w ułatwianie tworzenia SPA.