Ønsker du at øge dine færdigheder i React-udvikling? Byg din egen version af Hacker News ved hjælp af denne guide.

Hacker News er en populær hjemmeside blandt iværksættere og udviklere. Det indeholder indhold fokuseret på datalogi og iværksætteri.

Det enkle layout af Hacker News kan passe til visse personer. Men hvis du ønsker en mere tiltalende og personlig version, kan du bruge nyttige API'er til at skabe din egen tilpassede Hacker News-oplevelse. Opbygning af Hacker News-klonen kan også hjælpe dig med at styrke dine React-færdigheder.

Opsætning af projekt- og udviklingsserveren

Koden brugt i dette projekt er tilgængelig i en GitHub-depot og er gratis for dig at bruge under MIT-licensen.

For styling skal du kopiere indholdet af index.css fil fra lageret og indsæt dem i dit eget index.css fil. Hvis du vil have et kig på en live version af dette projekt, kan du tjekke dette ud demo.

De nødvendige pakker til dette projekt inkluderer:

  • React Router til håndtering af routing i Single Page Application (SPA).
  • instagram viewer
  • HTMLReactParser til at parse HTML returneret af Application Programming Interface (API).
  • MomentJS til håndtering af de datoer, der returneres af API'en.

Åbn terminalen og kør:

garn skabe vite

Du kan også bruge Node Package Manager (NPM) hvis du foretrækker det frem for garn. Kommandoen ovenfor skal bruge Vite build-værktøjet til at stilladsere et grundlæggende projekt. Navngiv dit projekt, og vælg, når du bliver bedt om rammen Reagere og indstil varianten til JavaScript.

Nu cd ind i projektmappen og installer de tidligere nævnte pakker ved at køre følgende kommandoer i terminalen:

garn tilføje html-react-parser
garn tilføj react-router-dom
garn tilføje øjeblik
garn dev

Når du har installeret alle pakkerne og startet udviklingsserveren, skal du åbne projektet i en hvilken som helst kodeeditor og oprette tre mapper i src mappe nemlig: komponenter, kroge, og sider.

I den komponenter mappe, tilføje to filer Comments.jsx og Navbar.jsx. I den kroge mappe, tilføje en fil useFetch.jsx. Derefter i sider mappe, tilføje to filer ListPage.jsx og PostPage.jsx.

Slet App.css fil og erstatte indholdet af main.jsx fil med følgende:

importere Reagere fra'reagere'
importere { BrowserRouter } fra'reager-router-dom'
importere ReactDOM fra'reager-dom/klient'
importere App fra'./App.jsx'
importere'./index.css'

ReactDOM.createRoot(dokument.getElementById('rod')).render(



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

I den App.jsx fil, fjern al boilerplate-koden og modificer filen, så du kun har den funktionelle komponent tilbage:

fungereApp() {
Vend tilbage (
<>
</>
)
}

eksportStandard App

Importer de nødvendige moduler:

importere { Ruter, rute } fra'reager-router-dom'
importere Listeside fra'./pages/ListPage'
importere Navbar fra'./components/Navbar'
importere Postside fra'./pages/PostPage'

Tilføj i React-fragmentet Ruter komponenter med tre Rute underordnede komponenter med stier: /, /:type, og /item/:id henholdsvis.


'/'
element={<> <Navbar /><Listeside /></>}>
</Route>
'/:type'
element={<> <Navbar /><Listeside /></>}>
</Route>
'/item/:id'
element={}>
</Route>
</Routes>

Oprettelse af useFetch Custom Hook

Dette projekt bruger to API'er. Den første API er ansvarlig for at hente listen over indlæg i en given kategori (type), mens den anden API er Algolia API, som er ansvarlig for at hente et bestemt indlæg og dets kommentarer.

Åbn useFetch.jsx fil, definer krogen som en standardeksport og importer useState og useEffect kroge.

importere { useState, useEffect } fra"reagere";
eksportStandardfungerebrugHent(type, id) {

}

Definer tre tilstandsvariable, nemlig: data, fejl, og Indlæser, med deres respektive indstillingsfunktioner.

konst [data, setData] = useState();
konst [fejl, setError] = useState(falsk);
konst [loading, setLoading] = useState(rigtigt);

Tilføj derefter a useEffect krog med afhængighederne: id og type.

useEffect(() => {
}, [id, type])

Næste i tilbagekaldsfunktionen skal du tilføje funktionen fetchData() for at hente dataene fra de relevante API'er. Hvis parameteren bestået er type, brug den første API. Ellers skal du bruge den anden API.

asynkronfungerehenteData() {
lade svar, url, parameter;
hvis (type) {
url = " https://node-hnapi.herokuapp.com/";
parameter = type.toLowerCase();
}
andethvis (id) {
url = " https://hn.algolia.com/api/v1/items/";
parameter = id.toLowerCase();
}
prøve {
svar = vente hente(`${url}${parameter}`);
} fangst (fejl) {
setError(rigtigt);
}

hvis (respons) hvis (response.status !== 200) {
setError(rigtigt);
} andet {
lade data = vente response.json();
sætLoading(falsk);
setData (data);
}
}
henteData();

Til sidst returnerer du Indlæser, fejl, og data tilstandsvariable som et objekt.

Vend tilbage { loading, error, data };

Gengivelse af listen over indlæg afhængigt af den ønskede kategori

Når brugeren navigerer til / eller /:type, React bør gengive Listeside komponent. For at implementere denne funktionalitet skal du først importere de nødvendige moduler:

importere { useNavigate, useParams } fra"reager-router-dom";
importere brugHent fra"../hooks/useFetch";

Definer derefter den funktionelle komponent og tildel derefter den dynamiske parameter, type til type variabel. Hvis den dynamiske parameter ikke er tilgængelig, skal du indstille type variabel til nyheder. Så ring til brugHent krog.

eksportStandardfungereListeside() {
lade { type } = useParams();
konst navigate = useNavigate();
hvis (!type) type = "nyheder";
konst { loading, error, data } = useFetch (type, nul);
}

Returner derefter den relevante JSX-kode afhængigt af hvilken af ​​de Indlæser, fejl, eller data variabler er sande.

hvis (fejl) {
Vend tilbage<div>Noget gik galt!div>
}

hvis (Indlæser) {
Vend tilbage<div>Indlæserdiv>
}

hvis (data) {
dokument.title = type.toUpperCase();
Vend tilbage<div>

'listetype'>{type}</div>
{data.map(vare =>
"vare">
"vare-titel"
onClick={() => naviger(`/vare/${item.id}`)}>
{item.title}
</div>
{item.domain &&
"vare-link"
onClick={() => åben(`${item.url}`)}>
({item.domain})</span>}
</div>)}
</div>
</div>
}

Oprettelse af PostPage-komponenten

Importer først de relevante moduler og komponenter, definer derefter standardfunktionskomponenten, tildel id dynamisk parameter til id variabel og, kalder brugHent krog. Sørg for at destrukturere svaret.

importere { Link, useParams } fra"reager-router-dom";
importere parse fra'html-react-parser';
importere øjeblik fra"øjeblik";
importere Kommentarer fra"../components/Comments";
importere brugHent fra"../hooks/useFetch";

eksportStandardfungerePostside() {
konst { id } = useParams();
konst { loading, error, data } = useFetch(nul, id);
}

Og ligesom med Listeside komponent, skal du gengive den relevante JSX baseret på tilstanden af ​​følgende variable: Indlæser, fejl, og data.

hvis (fejl) {
Vend tilbage<div>Noget gik galt!div>
}

hvis (Indlæser) {
Vend tilbage<div>Indlæserdiv>
}

hvis (data) {
dokument.title=data.title;
Vend tilbage<div>

"efter-titel">{data.title}</div>
"post-metadata">
{data.url &&
klassenavn="post-link">Besøg hjemmesiden</Link>}
"post-forfatter">{data.author}</span>
"efter tid">
{øjeblik (data.created_at).fromNow()}
</span>
</div>
{data.text &&
"post-tekst">
{parse (data.text)}</div>}
"post-kommentarer">
"kommentarer-etiket">Kommentarer</div>

</div>
</div>
}

Importer parse modul og øjeblik modul. Definer den funktionelle standardkomponent Kommentarer der tager i kommentarer Data array som en rekvisit, krydser gennem arrays og gengiver en Node komponent for hvert element.

importere parse fra'html-react-parser';
importere øjeblik fra"øjeblik";

eksportStandardfungereKommentarer({ commentsData }) {
Vend tilbage<>
{commentsData.map(kommentarData =><NodekommentarData={commentData}nøgle={commentData.id}
/>)}
</>
}

Dernæst skal du definere Node funktionel komponent lige under Kommentarer komponent. Det Node komponent gengiver kommentaren, metadata og svar på hver kommentar (hvis nogen) ved at gengive sig selv rekursivt.

fungereNode({ kommentardata }) {
Vend tilbage<divklassenavn="kommentar">
{
commentData.text &&
<>
'kommentar-metadata'>
{commentData.author}</span>

{øjeblik (commentData.created_at).fromNow()}
</span>
</div>
'kommentar-tekst'
>
{parse (commentData.text)}</div>
</>
}
'kommentar-svar'
>
{(commentData.children) &&
commentData.children.map(barn =>
)}
</div>
</div>
}

I kodeblokken ovenfor, parse er ansvarlig for at parse den HTML, der er gemt i commentData.text, mens øjeblik er ansvarlig for at analysere kommentartiden og returnere den relative tid ved hjælp af fra nu() metode.

Oprettelse af Navbar-komponenten

Åbn Navbar.jsx fil og importer NavLink modul fra reagere-router-dom modul. Til sidst skal du definere den funktionelle komponent og returnere en forælder nav element med fem NavLink elementer, der peger på de relevante kategorier (eller typer).

importere { NavLink } fra"reager-router-dom"

eksportStandardfungereNavbar() {
Vend tilbage<nav>
"/nyheder">Hjem</NavLink>
"/bedst">bedst</NavLink>
"/at vise">Vis</NavLink>
"/Spørg">Spørg</NavLink>
"/jobs">Jobs</NavLink>
</nav>
}

Tillykke! Du har lige bygget din egen front-end-klient til Hacker News.

Styrk dine reaktionsevner ved at bygge klonapplikation

Opbygning af en Hacker News-klon med React kan hjælpe med at styrke dine React-færdigheder og give en praktisk Single Page Application at arbejde på. Der er mange måder, du kan tage tingene videre på. For eksempel kan du tilføje muligheden for at søge efter indlæg og brugere til appen.

I stedet for at prøve at bygge din egen router fra bunden, er det bedre at bruge et værktøj bygget af fagfolk, der er dedikerede til at gøre det nemmere at oprette SPA'er.