Търсите да подобрите уменията си за развитие на React? Създайте своя собствена версия на Hacker News с помощта на това ръководство.
Hacker News е популярен уебсайт сред предприемачи и разработчици. Включва съдържание, фокусирано върху компютърните науки и предприемачеството.
Опростеното оформление на Hacker News може да подхожда на определени хора. Въпреки това, ако желаете по-привлекателна и персонализирана версия, можете да използвате полезни API, за да създадете свое собствено персонализирано изживяване с Hacker News. Освен това изграждането на клонинга на Hacker News може да ви помогне да затвърдите уменията си за React.
Настройка на проекта и сървъра за разработка
Кодът, използван в този проект, е наличен в a GitHub хранилище и е безплатен за използване под лиценза на MIT.
За стилизиране копирайте съдържанието на index.css файл от хранилището и ги поставете във вашия собствен index.css файл. Ако искате да разгледате версия на живо на този проект, можете да проверите това демонстрация.
Пакетите, необходими за този проект, включват:
- React Router за обработка на маршрутизирането в Едностранично приложение (SPA).
- HTMLReactParser за анализиране на HTML, върнат от Интерфейс за програмиране на приложения (API).
- MomentJS за обработка на датите, върнати от API.
Отворете терминала и стартирайте:
прежда създават vite
Можете също да използвате Мениджър на пакети на възли (NPM) ако го предпочитате пред прежда. Командата по-горе трябва да използва инструмента за изграждане на Vite за скеле на основен проект. Наименувайте проекта си и когато бъдете подканени за рамката, изберете Реагирайте и задайте варианта на JavaScript.
Сега cd в папката на проекта и инсталирайте споменатите по-рано пакети, като изпълните следните команди в терминала:
yarn добави html-react-parser
прежда добавете реакция-рутер-дом
момент добавяне на прежда
разработка на прежда
След като инсталирате всички пакети и стартирате сървъра за разработка, отворете проекта във всеки редактор на код и създайте три папки в src папка а именно: компоненти, кукички, и страници.
В компоненти папка, добавете два файла Comments.jsx и Navbar.jsx. В кукички папка, добавете един файл useFetch.jsx. Тогава в страници папка, добавете два файла ListPage.jsx и PostPage.jsx.
Изтрийте App.css файл и заменете съдържанието на main.jsx файл със следното:
импортиране Реагирайте от"реагира"
импортиране {BrowserRouter} от'react-router-dom'
импортиране ReactDOM от'react-dom/клиент'
импортиране Приложение от'./App.jsx'
импортиране'./index.css'
ReactDOM.createRoot(документ.getElementById("корен")).render(
</BrowserRouter>
</React.StrictMode>,
)
В App.jsx файл, премахнете целия шаблонен код и модифицирайте файла така, че да ви остане само функционалният компонент:
функцияПриложение() {
връщане (
<>
</>
)
}
износпо подразбиране Приложение
Импортирайте необходимите модули:
импортиране { Маршрути, Маршрут } от'react-router-dom'
импортиране ListPage от'./pages/ListPage'
импортиране Навигационна лента от'./components/Navbar'
импортиране PostPage от'./pages/PostPage'
Във фрагмента на React добавете Маршрути компоненти с три Маршрут дъщерни компоненти с пътища: /, /:type, и /item/:id съответно.
'/'
елемент={<> <Навигационна лента /><ListPage /></>}>
</Route>
'/:Тип'
елемент={<> <Навигационна лента /><ListPage /></>}>
</Route>
'/item/:id'
елемент={}>
</Route>
</Routes>
Създаване на потребителската кука useFetch
Този проект използва два API. Първият API отговаря за извличането на списъка с публикации в дадена категория (тип), докато вторият API е API на Algolia, който отговаря за извличането на определена публикация и нейните коментари.
Отвори useFetch.jsx файл, дефинирайте куката като експорт по подразбиране и импортирайте useState и useEffect кукички.
импортиране {useState, useEffect} от"реагира";
износпо подразбиранефункцияuseFetch(тип, id) {
}
Дефинирайте три променливи на състоянието, а именно: данни, грешка, и Зареждане, със съответните им функции за настройка.
конст [данни, setData] = useState();
конст [грешка, setError] = useState(невярно);
конст [зареждане, setLoading] = useState(вярно);
След това добавете a useEffect кука със зависимостите: документ за самоличност и Тип.
useEffect(() => {
}, [id, тип])
След това във функцията за обратно извикване добавете функцията fetchData() за извличане на данните от подходящите API. Ако предаденият параметър е Тип, използвайте първия API. В противен случай използвайте втория API.
асинхроненфункцияfetchData() {
позволявам отговор, url, параметър;
ако (Тип) {
url = " https://node-hnapi.herokuapp.com/";
параметър = type.toLowerCase();
}
другоако (документ за самоличност) {
url = " https://hn.algolia.com/api/v1/items/";
параметър = id.toLowerCase();
}
опитвам {
отговор = изчакайте извличане (`${url}${параметър}`);
} улов (грешка) {
setError(вярно);
}
ако (отговор) ако (отговор.състояние !== 200) {
setError(вярно);
} друго {
позволявам данни = изчакайте response.json();
setLoading(невярно);
setData (данни);
}
}
fetchData();
Накрая върнете Зареждане, грешка, и данни променливите на състоянието като обект.
връщане { зареждане, грешка, данни };
Изобразяване на списък с публикации в зависимост от заявената категория
Всеки път, когато потребителят навигира до / или /:type, React трябва да изобрази ListPage компонент. За да приложите тази функционалност, първо импортирайте необходимите модули:
импортиране {useNavigate, useParams} от"react-router-dom";
импортиране useFetch от"../hooks/useFetch";
След това дефинирайте функционалния компонент и след това задайте динамичния параметър, Тип към Тип променлива. Ако динамичният параметър не е наличен, задайте Тип променлива към Новини. След това се обадете на useFetch кука.
износпо подразбиранефункцияListPage() {
позволявам {тип} = useParams();
конст навигация = useNavigate();
ако (!тип) тип = "Новини";
конст { зареждане, грешка, данни } = useFetch (тип, нула);
}
След това върнете подходящия JSX код в зависимост от това кой от Зареждане, грешка, или данни променливи е вярно.
ако (грешка) {
връщане<див>Нещо се обърка!див>
}ако (Зареждане) {
връщане<див>Зарежданедив>
}
ако (данни) {
документ.title = type.toUpperCase();
връщане<див>'тип списък'>{type}</div>{data.map(вещ =>"вещ">"артикул-заглавие"
onClick={() => навигация(`/елемент/${item.id}`)}>
{item.title}
</div>
{item.domain &&
"артикул-връзка"
onClick={() => отворен(`${item.url}`)}>
({item.domain})</span>}
</div>)}
</div>
</div>
}
Създаване на компонент PostPage
Първо импортирайте подходящите модули и компоненти, след това дефинирайте функционалния компонент по подразбиране, задайте документ за самоличност динамичен параметър към документ за самоличност променлива и извикайте useFetch кука. Уверете се, че деструктурирате отговора.
импортиране { Връзка, useParams } от"react-router-dom";
импортиране анализирам от'html-react-parser';
импортиране момент от"момент";
импортиране Коментари от"../components/Comments";
импортиране useFetch от"../hooks/useFetch";
износпо подразбиранефункцияPostPage() {
конст { id } = useParams();
конст { зареждане, грешка, данни } = useFetch(нула, документ за самоличност);
}
И точно както при ListPage компонент, визуализира подходящия JSX въз основа на състоянието на следните променливи: Зареждане, грешка, и данни.
ако (грешка) {
връщане<див>Нещо се обърка!див>
}ако (Зареждане) {
връщане<див>Зарежданедив>
}
ако (данни) {
документ.title=data.title;
връщане<див>"след заглавие">{данни.заглавие}</div>"пост-метаданни">
{data.url &&
className="пост-линк">Посетете уебсайта</Link>}
"пост-автор">{data.author}</span>
"след време">
{moment (data.created_at).fromNow()}
</span>
</div>
{data.text &&"след текст">
{parse (data.text)}</div>}"след коментари">"коментари-етикет">Коментари</div>
</div>
</div>
}
Импортирайте анализирам модул и момент модул. Дефинирайте функционалния компонент по подразбиране Коментари който приема в commentsData масив като опора, преминава през масивите и изобразява a Възел компонент за всеки елемент.
импортиране анализирам от'html-react-parser';
импортиране момент от"момент";
износпо подразбиранефункцияКоментари({ commentsData }) {
връщане<>
{commentsData.map(commentData =><ВъзелcommentData={commentData}ключ={commentData.id}
/>)}
</>
}
След това дефинирайте Възел функционален компонент точно под Коментари компонент. The Възел компонент изобразява коментара, метаданните и отговаря на всеки коментар (ако има такъв) чрез рекурсивно изобразяване на себе си.
функцияВъзел({ commentData }) {
връщане<дивclassName="коментар">
{
commentData.text &&
<>
'коментар-метаданни'>
{commentData.author}</span>
{moment (commentData.created_at).fromNow()}
</span>
</div>
'коментар-текст'>
{parse (commentData.text)}</div>
</>
}
'коментар-отговори'>
{(commentData.children) &&
commentData.children.map(дете =>
)}
</div>
</div>
}
В кодовия блок по-горе, анализирам е отговорен за анализирането на HTML, съхраняван в commentData.text, докато момент отговаря за анализирането на времето на коментара и връщането на относителното време с помощта на от сега() метод.
Създаване на компонента Navbar
Отвори Navbar.jsx файл и импортирайте NavLink модул от реагират-рутер-дом модул. Накрая дефинирайте функционалния компонент и върнете родител нав елемент с пет NavLink елементи, сочещи към съответните категории (или типове).
импортиране { NavLink } от"react-router-dom"
износпо подразбиранефункцияНавигационна лента() {
връщане<нав>"/Новини">Начало</NavLink> "/най-добър">Най-добър</NavLink> "/покажи">Покажи</NavLink> "/питам">Попитайте</NavLink> "/работни места">Работа</NavLink>
</nav>
}
Поздравления! Току-що създадохте свой собствен клиент за Hacker News.
Затвърдете вашите React умения чрез изграждане на приложение за клониране
Изграждането на клонинг на Hacker News с React може да ви помогне да затвърдите уменията си за React и да осигурите практично приложение за една страница, върху което да работите. Има много начини, по които можете да продължите нещата. Например, можете да добавите възможност за търсене на публикации и потребители към приложението.
Вместо да се опитвате да създадете свой собствен рутер от нулата, по-добре е да използвате инструмент, създаден от професионалисти, които са посветени на улесняването на създаването на SPA.