/ / Cách tạo bản sao Tin tức Hacker bằng React

Cách tạo bản sao Tin tức Hacker bằng React

Hacker News là một trang web phổ biến giữa các doanh nhân và nhà phát triển. Nó có nội dung tập trung vào khoa học máy tính và tinh thần kinh doanh.


Bố cục đơn giản của Hacker News có thể phù hợp với một số cá nhân. Tuy nhiên, nếu bạn muốn một phiên bản hấp dẫn và được cá nhân hóa hơn, bạn có thể sử dụng các API hữu ích để tạo trải nghiệm Hacker News tùy chỉnh của riêng bạn. Ngoài ra, xây dựng bản sao Hacker News có thể giúp bạn củng cố kỹ năng Phản ứng của mình.


Thiết lập máy chủ dự án và phát triển

Mã được sử dụng trong dự án này có sẵn trong kho lưu trữ GitHub và bạn được sử dụng miễn phí theo giấy phép MIT.

Để tạo kiểu, sao chép nội dung của chỉ mục.css tệp từ kho lưu trữ và dán chúng vào tệp của riêng bạn chỉ mục.css tài liệu. Nếu bạn muốn xem phiên bản trực tiếp của dự án này, bạn có thể xem bản demo này.

Các gói cần thiết cho dự án này bao gồm:

Mở terminal và chạy:

 yarn create vite

Bạn cũng có thể sử dụng Trình quản lý gói nút (NPM) nếu bạn thích nó hơn sợi. Lệnh trên nên sử dụng công cụ xây dựng Vite để dàn dựng một dự án cơ bản. Đặt tên cho dự án của bạn và khi được nhắc về khung, hãy chọn Phản ứng và đặt biến thể thành JavaScript.

Hiện nay đĩa CD vào thư mục dự án và cài đặt các gói được đề cập trước đó bằng cách chạy các lệnh sau trong thiết bị đầu cuối:

 yarn add html-react-parser
yarn add react-router-dom
yarn add moment
yarn dev

Sau khi cài đặt tất cả các gói và khởi động máy chủ phát triển, hãy mở dự án trong bất kỳ trình chỉnh sửa mã nào và tạo ba thư mục trong src thư mục cụ thể là: các thành phần, móctrang.

bên trong các thành phần thư mục, thêm hai tập tin Bình luận.jsxThanh điều hướng.jsx. bên trong móc thư mục, thêm một tập tin sử dụngFetch.jsx. Sau đó trong trang thư mục, thêm hai tập tin ListPage.jsxPostPage.jsx.

xóa Ứng dụng.css tập tin và thay thế nội dung của chính.jsx tập tin với nội dung sau:

 import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
)

bên trong Ứng dụng.jsx tệp, hãy xóa tất cả mã soạn sẵn và sửa đổi tệp sao cho bạn chỉ còn lại thành phần chức năng:

 function App() {
  return (
    <>
    </>
  )
}

export default App

Nhập các mô-đun cần thiết:

 import { Routes, Route } from 'react-router-dom'
import ListPage from './pages/ListPage'
import Navbar from './components/Navbar'
import PostPage from './pages/PostPage'

Trong đoạn React, thêm tuyến đường thành phần với ba Tuyến đường các thành phần con có đường dẫn: /, /:kiểu/mục/:id tương ứng.

 <Routes>
    <Route path="https://www.smartreviewaz.com/"
    element={<> <Navbar /><ListPage /></>}>
   </Route>
    <Route path='/:type'
    element={<> <Navbar /><ListPage /></>}>
   </Route>
    <Route path='/item/:id'
    element={<PostPage />}>
   </Route>
</Routes>

Tạo móc tùy chỉnh useFetch

Dự án này sử dụng hai API. API đầu tiên chịu trách nhiệm tìm nạp danh sách các bài đăng trong một danh mục (loại) nhất định, trong khi API thứ hai là API Algolia chịu trách nhiệm tìm nạp một bài đăng cụ thể và nhận xét của nó.

Mở sử dụngFetch.jsx tệp, hãy xác định hook làm xuất mặc định và nhập sử dụngStatesử dụnghiệu ứng móc câu.

 import { useState, useEffect } from "react";
export default function useFetch(type, id) {

}

Xác định ba biến trạng thái cụ thể là: dữ liệu, lỗiđang tảivới các hàm setter tương ứng của chúng.

 const [data, setData] = useState();
const [error, setError] = useState(false);
const [loading, setLoading] = useState(true);

Sau đó, thêm một sử dụnghiệu ứng hook với các phụ thuộc: nhận dạngkiểu.

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

Tiếp theo trong chức năng gọi lại, hãy thêm chức năng tìm nạp dữ liệu() để tìm nạp dữ liệu từ các API thích hợp. Nếu tham số truyền vào là kiểu, hãy sử dụng API đầu tiên. Nếu không, hãy sử dụng API thứ hai.

 async function fetchData() {
    let response, url, parameter;
    if (type) {
       url = "https://node-hnapi.herokuapp.com/";
       parameter = type.toLowerCase();
   }
    else if (id) {
       url = "https://hn.algolia.com/api/v1/items/";
        parameter = id.toLowerCase();
   }
    try {
        response = await fetch(`${url}${parameter}`);
    } catch (error) {
        setError(true);
    }

    if (response) if (response.status !== 200) {
        setError(true);
    } else {
        let data = await response.json();
        setLoading(false);
        setData(data);
    }
}
fetchData();

Cuối cùng, trả lại đang tải, lỗidữ liệu các biến trạng thái như một đối tượng.

 return { loading, error, data };

Hiển thị danh sách bài viết tùy thuộc vào danh mục được yêu cầu

Bất cứ khi nào người dùng điều hướng đến / hoặc /:kiểuReact sẽ hiển thị Trang danh sách thành phần. Để triển khai chức năng này, trước tiên, hãy nhập các mô-đun cần thiết:

 import { useNavigate, useParams } from "react-router-dom";
import useFetch from "../hooks/useFetch";

Sau đó, xác định thành phần chức năng và sau đó gán tham số động, kiểu đến kiểu Biến đổi. Nếu tham số động không khả dụng, hãy đặt kiểu biến thành Tin tức. Sau đó, gọi cho sử dụngFetch cái móc.

 export default function ListPage() {
    let { type } = useParams();
    const navigate = useNavigate();
    if (!type) type = "news";
    const { loading, error, data } = useFetch(type, null);
}

Tiếp theo, trả lại mã JSX thích hợp tùy thuộc vào mã nào trong số đang tải, lỗihoặc dữ liệu biến là đúng.

 if (error) {
    return <div>Something went wrong!</div>
}

if (loading) {
    return <div>Loading</div>
}

if (data) {
    document.title = type.toUpperCase();
    return <div>
        <div className='list-type'>{type}</div>
           <div>{data.map(item =>
              <div key={item.id} className="item">
                 <div className="item-title"
                 onClick={() => navigate(`/item/${item.id}`)}>
                    {item.title}
                </div>
            {item.domain &&
           <span className="item-link"
            onClick={() => open(`${item.url}`)}>
            ({item.domain})</span>}
           </div>)}
       </div>
    </div>
}

Tạo thành phần PostPage

Đầu tiên, nhập các mô-đun và thành phần thích hợp, sau đó xác định thành phần chức năng mặc định, gán nhận dạng tham số động cho nhận dạng biến và, gọi sử dụngFetch cái móc. Hãy chắc chắn rằng bạn hủy cấu trúc phản hồi.

 import { Link, useParams } from "react-router-dom";
import parse from 'html-react-parser';
import moment from "moment";
import Comments from "../components/Comments";
import useFetch from "../hooks/useFetch";

export default function PostPage() {
    const { id } = useParams();
    const { loading, error, data } = useFetch(null, id);
}

Và cũng giống như với Trang danh sách thành phần, hiển thị JSX thích hợp dựa trên trạng thái của các biến sau: đang tải, lỗidữ liệu.

 if (error) {
    return <div>Something went wrong!</div>
}

if (loading) {
    return <div>Loading</div>
}

if (data) {
    document.title=data.title;
    return <div>
        <div className="post-title">{data.title}</div>
        <div className="post-metadata">
            {data.url &&
           <Link to={data.url}
            className="post-link">Visit Website</Link>}
            <span className="post-author">{data.author}</span>
            <span className="post-time">
             {moment(data.created_at).fromNow()}
            </span>
        </div>
        {data.text &&
       <div className="post-text">
       {parse(data.text)}</div>}
        <div className="post-comments">
            <div className="comments-label">Comments</div>
            <Comments commentsData={data.children} />
        </div>
    </div>
}

Nhập khẩu phân tích cú pháp mô-đun và chốc lát mô-đun. Xác định thành phần chức năng mặc định Bình luận mà mất trong bình luậnDữ liệu mảng làm chỗ dựa, duyệt qua các mảng và hiển thị một Nút thành phần cho từng phần tử.

 import parse from 'html-react-parser';
import moment from "moment";

export default function Comments({ commentsData }) {
    return <>
        {commentsData.map(commentData => <Node commentData={commentData} key={commentData.id}
        />)}
    </>
}

Tiếp theo, xác định Nút thành phần chức năng ngay dưới Bình luận thành phần. Các Nút thành phần hiển thị nhận xét, siêu dữ liệu và trả lời từng nhận xét (nếu có) bằng cách hiển thị đệ quy chính nó.

 function Node({ commentData }) {
    return <div className="comment">
        {
          commentData.text &&
            <>
                <div className='comment-metadata'>
                    <span>{commentData.author}</span>
                    <span>
                        {moment(commentData.created_at).fromNow()}
                   </span>
                </div>
                <div className='comment-text'>
               {parse(commentData.text)}</div>
            </>
        }
        <div className='comment-replies'>
       {(commentData.children) &&
       commentData.children.map(child =>
       <Node commentData={child} key={child.id}/>)}
       </div>
    </div>
}

Trong khối mã trên, phân tích cú pháp chịu trách nhiệm phân tích cú pháp HTML được lưu trữ trong bình luậnData.texttrong khi chốc lát chịu trách nhiệm phân tích thời gian nhận xét và trả lại thời gian tương đối bằng cách sử dụng từ giờ() phương pháp.

Tạo Thành phần Navbar

Mở Thanh điều hướng.jsx tập tin và nhập khẩu Liên kết điều hướng mô-đun từ Reac-router-dom mô-đun. Cuối cùng, xác định thành phần chức năng và trả về cha mẹ điều hướng yếu tố với năm Liên kết điều hướng các phần tử trỏ đến các danh mục (hoặc loại) thích hợp.

 import { NavLink } from "react-router-dom"

export default function Navbar() {
    return <nav>
        <NavLink to="/news">Home</NavLink>
        <NavLink to="/best">Best</NavLink>
        <NavLink to="/show">Show</NavLink>
        <NavLink to="/ask">Ask</NavLink>
        <NavLink to="/jobs">Jobs</NavLink>
    </nav>
}

Chúc mừng! Bạn vừa xây dựng ứng dụng khách đầu cuối của riêng mình cho Hacker News.

Ảnh chụp màn hình của bản sao đã hoàn thành

Củng cố kỹ năng phản ứng của bạn bằng cách xây dựng ứng dụng nhân bản

Xây dựng một bản sao Hacker News bằng React có thể giúp củng cố các kỹ năng React của bạn và cung cấp một Ứng dụng Trang đơn thực tế để hoạt động. Có nhiều cách bạn có thể đưa mọi thứ đi xa hơn. Ví dụ: bạn có thể thêm khả năng tìm kiếm bài đăng và người dùng vào ứng dụng.

Thay vì cố gắng xây dựng bộ định tuyến của riêng bạn từ đầu, tốt hơn là sử dụng một công cụ được xây dựng bởi các chuyên gia, những người chuyên giúp tạo SPA dễ dàng hơn.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *