Wil je je React-ontwikkelingsvaardigheden naar een hoger niveau tillen? Bouw je eigen versie van Hacker News met behulp van deze gids.

Hacker News is een populaire website onder ondernemers en ontwikkelaars. Het bevat inhoud gericht op informatica en ondernemerschap.

De eenvoudige lay-out van Hacker News kan geschikt zijn voor bepaalde personen. Als u echter een aantrekkelijkere en gepersonaliseerde versie wenst, kunt u handige API's gebruiken om uw eigen aangepaste Hacker News-ervaring te creëren. Ook kan het bouwen van de Hacker News-kloon u helpen uw React-vaardigheden te verstevigen.

De project- en ontwikkelingsserver opzetten

De code die in dit project wordt gebruikt, is beschikbaar in een GitHub-opslagplaats en is gratis voor u om te gebruiken onder de MIT-licentie.

Kopieer voor styling de inhoud van het index.css bestand uit de repository en plak ze in uw eigen index.css bestand. Als je een live versie van dit project wilt zien, kun je dit bekijken demo.

De pakketten die nodig zijn voor dit project omvatten:

  • React Router voor het afhandelen van de routing in de Applicatie met één pagina (SPA).
  • HTMLReactParser voor het ontleden van de HTML geretourneerd door de Application Programming Interface (API).
  • MomentJS voor het afhandelen van de datums die door de API worden geretourneerd.

Open de terminal en voer uit:

garen creëren vite

U kunt ook de Knooppuntpakketbeheerder (NPM) als je dat liever hebt dan garen. De opdracht hierboven zou de Vite build-tool moeten gebruiken om een ​​basisproject te ondersteunen. Geef uw project een naam en kies wanneer u om het raamwerk wordt gevraagd Reageer en zet de variant op javascript.

Nu CD in de projectmap en installeer de eerder genoemde pakketten door de volgende opdrachten in de terminal uit te voeren:

garen voeg html-react-parser toe
garen voeg reactie-router-dom toe
garen toevoegen moment
garen ontwikkelaar

Nadat u alle pakketten hebt geïnstalleerd en de ontwikkelingsserver hebt gestart, opent u het project in een willekeurige code-editor en maakt u drie mappen in het src map namelijk: componenten, haken, En Pagina's.

In de componenten map, voeg twee bestanden toe Opmerkingen.jsx En Navbar.jsx. In de haken map, voeg een bestand toe gebruikFetch.jsx. Dan in de Pagina's map, voeg twee bestanden toe LijstPage.jsx En PostPage.jsx.

Verwijder de App.css bestand en vervang de inhoud van het main.jsx bestand met het volgende:

importeren Reageer van'Reageer'
importeren { BrowserRouter } van'reageren-router-dom'
importeren ReactDOM van'react-dom/klant'
importeren app van'./App.jsx'
importeren'./index.css'

ReactDOM.createRoot(document.getElementById('wortel')).veroorzaken(



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

In de App.jsx bestand, verwijder alle boilerplate-code en wijzig het bestand zodanig dat alleen de functionele component overblijft:

functieapp() {
opbrengst (
<>
</>
)
}

exporterenstandaard app

Importeer de benodigde modules:

importeren { Routes, Route } van'reageren-router-dom'
importeren LijstPagina van'./pagina's/LijstPagina'
importeren Navigatiebalk van'./componenten/Navbar'
importeren Berichtpagina van'./pagina's/PostPage'

Voeg in het React-fragment de Routes onderdelen met drie Route onderliggende componenten met paden: /, /:type, En /item/:id respectievelijk.


'/'
element={<> <Navigatiebalk /><LijstPagina /></>}>
</Route>
'/:type'
element={<> <Navigatiebalk /><LijstPagina /></>}>
</Route>
'/item ID'
element={}>
</Route>
</Routes>

De useFetch Custom Hook maken

Dit project gebruikt twee API's. De eerste API is verantwoordelijk voor het ophalen van de lijst met berichten in een bepaalde categorie (type), terwijl de tweede API de Algolia API is die verantwoordelijk is voor het ophalen van een bepaald bericht en zijn opmerkingen.

Open de gebruikFetch.jsx bestand, definieer de hook als een standaard export en importeer het gebruikState En gebruikEffect haken.

importeren { useState, useEffect } van"Reageer";
exporterenstandaardfunctiegebruikFetch(typ, idd) {

}

Definieer drie toestandsvariabelen namelijk: gegevens, fout, En bezig met laden, met hun respectieve instelfuncties.

const [gegevens, setData] = useState();
const [fout, setError] = useState(vals);
const [laden, setLaden] = useState(WAAR);

Voeg dan een toe gebruikEffect haak met de afhankelijkheden: ID kaart En type.

gebruikEffect(() => {
}, [ID Type])

Voeg vervolgens in de callback-functie de functie toe gegevens ophalen() om de gegevens van de juiste API's op te halen. Als de doorgegeven parameter is type, gebruik de eerste API. Gebruik anders de tweede API.

asynchroonfunctiegegevens ophalen() {
laten reactie, url, parameter;
als (typ) {
URL = " https://node-hnapi.herokuapp.com/";
parameter = type.toLowerCase();
}
andersals (ID kaart) {
URL = " https://hn.algolia.com/api/v1/items/";
parameter = id.toLowerCase();
}
poging {
reactie = wachten ophalen(`${url}${parameter}`);
} vangst (fout) {
setFout(WAAR);
}

als (antwoord) als (antwoord.status !== 200) {
setFout(WAAR);
} anders {
laten gegevens = wachten reactie.json();
setBezig met laden(vals);
setData (gegevens);
}
}
gegevens ophalen();

Retourneer ten slotte de bezig met laden, fout, En gegevens toestandsvariabelen als een object.

opbrengst { laden, fout, data };

De lijst met berichten weergeven afhankelijk van de gevraagde categorie

Wanneer de gebruiker navigeert naar / of /:type, React zou de LijstPagina bestanddeel. Om deze functionaliteit te implementeren, importeert u eerst de benodigde modules:

importeren { useNavigate, useParams } van"reageren-router-dom";
importeren gebruikFetch van"../hooks/useFetch";

Definieer vervolgens de functionele component en wijs vervolgens de dynamische parameter toe, type naar de type variabel. Als de dynamische parameter niet beschikbaar is, stelt u de type variabel naar nieuws. Bel dan de gebruikFetch haak.

exporterenstandaardfunctieLijstPagina() {
laten {type} = useParams();
const navigeren = gebruikNavigeren();
als (!type) typ = "nieuws";
const { laden, fout, data } = useFetch (type, nul);
}

Retourneer vervolgens de juiste JSX-code, afhankelijk van welke van de bezig met laden, fout, of gegevens variabelen is waar.

als (fout) {
opbrengst<div>Er is iets fout gegaan!div>
}

als (bezig met laden) {
opbrengst<div>Bezig met ladendiv>
}

als (gegevens) {
document.titel = type.toUpperCase();
opbrengst<div>

'lijsttype'>{type}</div>
{data.map(item =>
"item">
"titel van het item"
onClick={() => navigeren(`/item/${item.id}`)}>
{titel van het item}
</div>
{item.domein &&
"item-link"
onClick={() => openen(`${item.url}`)}>
({item.domein})</span>}
</div>)}
</div>
</div>
}

De PostPage-component maken

Importeer eerst de juiste modules en componenten, definieer vervolgens de standaard functionele component, wijs de ID kaart dynamische parameter aan de ID kaart variabele en bel de gebruikFetch haak. Zorg ervoor dat je de respons destructureert.

importeren { Link, useParams } van"reageren-router-dom";
importeren ontleed van'html-reageer-parser';
importeren moment van"moment";
importeren Opmerkingen van"../componenten/Opmerkingen";
importeren gebruikFetch van"../hooks/useFetch";

exporterenstandaardfunctieBerichtpagina() {
const { id } = useParams();
const { laden, fout, data } = useFetch(nul, ID kaart);
}

En net als bij de LijstPagina component, geef de juiste JSX weer op basis van de status van de volgende variabelen: bezig met laden, fout, En gegevens.

als (fout) {
opbrengst<div>Er is iets fout gegaan!div>
}

als (bezig met laden) {
opbrengst<div>Bezig met ladendiv>
}

als (gegevens) {
document.titel=gegevens.titel;
opbrengst<div>

"post-titel">{gegevens.titel}</div>
"post-metadata">
{data.url &&
classNaam="post-link">Bezoek website</Link>}
"post-auteur">{gegevens.auteur}</span>
"post tijd">
{moment (data.created_at).fromNow()}
</span>
</div>
{data.tekst &&
"post-tekst">
{ontleden (data.text)}</div>}
"opmerkingen plaatsen">
"opmerkingen-label">Opmerkingen</div>

</div>
</div>
}

Importeer de ontleed moduul en de moment moduul. Definieer de standaard functionele component Opmerkingen dat neemt de opmerkingenGegevens array als een prop, doorloopt de arrays en geeft a weer Knooppunt component voor elk element.

importeren ontleed van'html-reageer-parser';
importeren moment van"moment";

exporterenstandaardfunctieOpmerkingen({ commentsGegevens }) {
opbrengst<>
{opmerkingenData.map(commentaarGegevens =><KnooppuntcommentaarGegevens={commentData}sleutel={commentData.id}
/>)}
</>
}

Definieer vervolgens de Knooppunt functionele component recht onder de Opmerkingen bestanddeel. De Knooppunt component geeft de opmerking, metadata en antwoorden op elke opmerking (indien aanwezig) weer door zichzelf recursief weer te geven.

functieKnooppunt({commentaarGegevens}) {
opbrengst<divnaam van de klasse="opmerking">
{
commentData.text &&
<>
'commentaar-metadata'>
{commentData.auteur}</span>

{moment (commentData.created_at).fromNow()}
</span>
</div>
'commentaar-tekst'
>
{ontleden (commentData.text)}</div>
</>
}
'commentaar-antwoorden'
>
{(commentaarData.kinderen) &&
commentData.children.map(kind =>
)}
</div>
</div>
}

In het codeblok hierboven, ontleed is verantwoordelijk voor het ontleden van de HTML die is opgeslagen in commentData.tekst, terwijl moment is verantwoordelijk voor het ontleden van de commentaartijd en het retourneren van de relatieve tijd met behulp van de vanaf nu() methode.

De navigatiebalkcomponent maken

Open de Navbar.jsx bestand en importeer het NavLink moduul uit de reactie-router-dom moduul. Definieer ten slotte de functionele component en retourneer een ouder navigatie element met vijf NavLink elementen die naar de juiste categorieën (of typen) verwijzen.

importeren { NavLink } van"reageren-router-dom"

exporterenstandaardfunctieNavigatiebalk() {
opbrengst<navigatie>
"/nieuws">Thuis</NavLink>
"/best">Beste</NavLink>
"/show">Tonen</NavLink>
"/vragen">Vraag</NavLink>
"/banen">Vacatures</NavLink>
</nav>
}

Gefeliciteerd! Je hebt zojuist je eigen front-end client gebouwd voor Hacker News.

Verstevig uw reactievaardigheden door een kloontoepassing te bouwen

Het bouwen van een Hacker News-kloon met React kan helpen om uw React-vaardigheden te verstevigen en een praktische Single Page Application te bieden om aan te werken. Er zijn veel manieren waarop u verder kunt gaan. U kunt bijvoorbeeld de mogelijkheid toevoegen om naar berichten en gebruikers te zoeken in de app.

In plaats van te proberen uw eigen router helemaal opnieuw te bouwen, is het beter om een ​​tool te gebruiken die is gebouwd door professionals die zich inzetten om het gemakkelijker te maken om SPA's te maken.