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).
- 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.