返回

React仿知乎移动端想法页:小白React入门必修课!

前端

React作为前端使用频率最高的三大框架之一,其组件化开发思想备受推崇。对于学习过React的前端小伙伴来说,“React中一切都是组件”这句话可谓耳熟能详。

在本文中,我们将通过一个实战项目——React仿知乎移动端想法页,来详细介绍React组件化开发的应用。通过这个项目,你将学习到如何将复杂组件拆分为更小的可重用组件,以及如何管理组件之间的通信和状态。

前言

在这个React实战项目中,我们将构建一个仿知乎移动端想法页。在这个页面上,用户可以查看想法列表,并可以对想法进行点赞、评论和分享。

这个项目将涉及到以下知识点:

  • React组件化开发
  • React状态管理
  • React事件处理
  • React路由
  • React动画

项目结构

项目结构如下:

├── App.js
├── components
│   ├── Idea.js
│   ├── IdeaList.js
│   ├── Header.js
│   ├── Footer.js
│   └── NotFound.js
├── index.js
├── package.json
└── README.md
  • App.js:应用程序的主组件,负责管理路由和页面布局。
  • components:组件文件夹,存放所有组件。
  • Idea.js:想法组件,负责显示单个想法。
  • IdeaList.js:想法列表组件,负责显示所有想法。
  • Header.js:页头组件,负责显示页面标题和导航栏。
  • Footer.js:页脚组件,负责显示页脚信息。
  • NotFound.js:404页面组件,负责显示页面未找到信息。
  • index.js:应用程序的入口文件,负责加载应用程序。
  • package.json:应用程序的包配置文件。
  • README.md:应用程序的README文件。

构建过程

1. 安装依赖

首先,我们需要安装项目所需的依赖。

npm install

2. 创建组件

接下来,我们需要创建组件。

mkdir components
cd components
touch Idea.js IdeaList.js Header.js Footer.js NotFound.js

3. 编写组件

然后,我们需要编写组件。

// Idea.js
import React from 'react';

const Idea = (props) => {
  const { idea } = props;

  return (
    <div className="idea">
      <div className="idea-title">{idea.title}</div>
      <div className="idea-content">{idea.content}</div>
      <div className="idea-actions">
        <button onClick={() => props.onUpvote(idea)}>👍</button>
        <button onClick={() => props.onDownvote(idea)}>👎</button>
        <button onClick={() => props.onComment(idea)}>💬</button>
        <button onClick={() => props.onShare(idea)}>🚀</button>
      </div>
    </div>
  );
};

export default Idea;

// IdeaList.js
import React, { useState } from 'react';
import Idea from './Idea';

const IdeaList = (props) => {
  const { ideas } = props;
  const [sortField, setSortField] = useState('created_at');

  const sortedIdeas = ideas.sort((a, b) => {
    if (a[sortField] < b[sortField]) {
      return -1;
    } else if (a[sortField] > b[sortField]) {
      return 1;
    } else {
      return 0;
    }
  });

  return (
    <div className="idea-list">
      <div className="idea-list-header">
        <div className="idea-list-sort">
          <button onClick={() => setSortField('created_at')}>按时间排序</button>
          <button onClick={() => setSortField('upvotes')}>按赞数排序</button>
          <button onClick={() => setSortField('comments')}>按评论数排序</button>
        </div>
      </div>
      <div className="idea-list-body">
        {sortedIdeas.map((idea) => (
          <Idea
            key={idea.id}
            idea={idea}
            onUpvote={() => props.onUpvote(idea)}
            onDownvote={() => props.onDownvote(idea)}
            onComment={() => props.onComment(idea)}
            onShare={() => props.onShare(idea)}
          />
        ))}
      </div>
    </div>
  );
};

export default IdeaList;

// Header.js
import React from 'react';

const Header = () => {
  return (
    <div className="header">
      <div className="header-title">知乎</div>
      <div className="header-nav">
        <a href="#">首页</a>
        <a href="#">想法</a>
        <a href="#">问题</a>
        <a href="#">专栏</a>
        <a href="#">更多</a>
      </div>
    </div>
  );
};

export default Header;

// Footer.js
import React from 'react';

const Footer = () => {
  return (
    <div className="footer">
      <div className="footer-copyright">Copyright © 2023 知乎</div>
    </div>
  );
};

export default Footer;

// NotFound.js
import React from 'react';

const NotFound = () => {
  return (
    <div className="not-found">
      <h1>404</h1>
      <h2>页面未找到</h2>
    </div>
  );
};

export default NotFound;

4. 编写应用程序

接下来,我们需要编写应用程序。

// App.js
import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import IdeaList from './components/IdeaList';
import Header from './components/Header';
import Footer from './components/Footer';
import NotFound from './components/NotFound';

const App = () => {
  const [ideas, setIdeas] = useState([
    {
      id: 1,
      title: 'React Hooks',
      content: 'React Hooks are a new feature in React that allow you to use state and other React features without writing a class.',
      upvotes: 10,
      comments: 5,
      shares: 2
    },
    {
      id: 2,
      title: 'Functional Components',
      content: 'Functional components are a new type of component in React that are defined as arrow functions.',
      upvotes: 8,
      comments: 3,
      shares: 1
    },
    {
      id: 3,
      title: 'Context API',
      content: 'The Context API is a way to share data between components without passing props down through the component tree.',
      upvotes: 6,
      comments: 2,
      shares: 0
    }
  ]);

  const onUpvote = (idea) => {
    const updatedIdeas = ideas.map((i) => {
      if (i.id === idea.id) {
        return {
          ...i,
          upvotes: i.upvotes + 1
        };
      } else {
        return i;
      }
    });

    setIdeas(updatedIdeas);
  };

  const onDownvote = (idea) => {
    const updatedIdeas = ideas.map((i) => {
      if (i.id === idea.id) {
        return {
          ...i,
          upvotes: i.upvotes - 1
        };
      } else {
        return i;
      }
    });

    setIdeas(updatedIdeas);
  };

  const onComment = (idea) => {
    console.log(`Comment on idea ${idea.id}`);
  };

  const onShare = (idea) => {
    console.log(`Share idea ${idea.id}`);
  };

  return (
    <Router>
      <div className="app">
        <Header />
        <div className="app-body">
          <Routes>
            <Route path="/" element={<IdeaList ideas={ideas} onUpvote={onUpvote}