React + Node 单页应用「一」前端搭建

项目地址
预览地址
原文地址javascript

记录最近作的一个 demo,前端使用 React,用 React Router 实现前端路由,Koa 2 搭建 API Server, 最后经过 Nginx 作请求转发。css

这是第一篇,主要介绍下前端代码的构建、React router 使用中遇到问题,以及前端开发完成后部署相关工做。html

功能介绍

GitCard 能够经过 GitHub 受权获取用户基本信息前端

  • 在首页模块,能够查看最近登陆的用户,并点击头像查看该用户的详细信息
  • /Comment 模块中能够发表评论,并删除本身的评论
  • /Detail 模块中能够查看用户在 Github 上的基本信息(代码库,Follower、Following 以及更多开发的信息),你能够在这个基础上作更多有意思的事情,支持 Follow 和 Unfollow 操做,固然,你能够加上 Star 和 Unstar 操做,殊途同归。🈳️

依赖版本

  • 构建工具: create-react-app
  • react: 16.0.0
  • react-router: 4.2.2
  • 网络请求: axios
  • UI: material-ui

项目搭建

前端构建工具使用 React 官方的 create-react-app,快速生成可执行的项目结构。下面是快速上手流程,详细的内容能够参见 官方文档java

// 全局安装 create-react-app
npm install -g create-react-app

//生成项目,项目名 my-app(自定义)
create-react-app my-app
cd my-app

// 安装依赖
npm install
// 开发环境
npm start
// 打包
npm run build

生成项目后,项目文件结构以下,npm run build 执行后,目录下会出现 /build/ 目录,存放构建后的文件。node

/**
 * my-app 目录结构
 */
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public 
│   └── favicon.ico
│   └── index.html
│   └── manifest.json
└── src
    └── App.css
    └── App.js //项目入口
    └── App.test.js
    └── index.css
    └── index.js
    └── logo.svg
    └── registerServiceWorker.js

咱们在 /src/ 目录下新建 /components/ 目录,用于存放本次项目中的全部自定义组件,最终的目录以下react

.
├── README.md
├── build
├── package.json
├── public
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── components
│   │   ├── Comments
│   │   │   ├── comment.css
│   │   │   └── index.jsx
│   │   ├── Events
│   │   │   └── index.jsx
│   │   ├── HomePage
│   │   │   └── index.jsx
│   │   ├── UserDetail
│   │   │   └── index.jsx
│   │   └── layouts
│   │       ├── Header.jsx
│   │       └── SideMenu.jsx
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   ├── registerServiceWorker.js
│   └── utils
│       ├── api.jsx
│       ├── fetch.jsx
│       └── keygen.js
└── yarn.lock

前端路由

此次作的项目是单页应用,经过 React router 实现前端路由,Container 经过路由选择显示的模块内容,在 Header 显示路由切换入口,页面结构图以下。ios

/src/App.js 布局并设置路由,将 HeaderContainer 包在 Router 下,在 Header 的 Menu 组件中设置路由连接,并在 Container 中设置路由指向对应组件。git

Menu 中 Detail 连接在用户受权登陆后就指向登陆用户信息,不然跳转到受权登陆页面。github

// 引入 React router
import {
  BrowserRouter as Router,
  Link,
  Route
} from "react-router-dom"

// 在 layout-content 中设置路由对应的组件
<Router>
    <div className="App">
        <Header loginInfo={this.state.loginInfo}></Header>
        <div className="layout-container">
            <div className="layout-content">
                <Route exact path="/" component={ HomePage } ></Route>
                <Route path="/user/:userid" component={ UserDetail } ></Route>
                <Route path="/events" component={Events}></Route>
                <Route path="/comments" render={ ()=><Comments loginInfo={this.state.loginInfo} /> }></Route>
            </div>
        </div>
    </div>
</Router>

// 在 Header 中设置 Link 
<Menu>
    <Link to="/">
        <MenuItem primaryText="Home" />
    </Link>
    <Link to="/comments">
        <MenuItem primaryText="Comments"/>
    </Link>
    {
    this.props.loginInfo.login ?
      (<Link to={  '/user/' + this.props.loginInfo.login }>
            <MenuItem primaryText="Detail" />
      </Link>)
      : (<MenuItem primaryText="Login" onClick={this.login} />)
    }
</Menu>

数据操做

路由下发数据

上面的代码的路由中,咱们经过两种方式下发数据到组件中,经过路由参数将用户 ID 下发到 Detail 组件,以及经过 props 讲用户基本信息下发到 Comment 组件中。

// 经过路由参数下发的 Link 以及对应的 Route
<Link to={  '/user/' + this.props.loginInfo.login }><MenuItem primaryText="Detail" /></Link>
<Route path="/user/:userid" component={ UserDetail } ></Route>

// 经过 props 下发
<Route path="/comments" render={ ()=><Comments loginInfo={this.state.loginInfo} /> }></Route>

经过路由参数获取下发数据,若是在 /user/lijundong 跳转到 /user/free-free 会出现路由改变,数据不刷新的状况,这里须要用 componentWillReceiveProps(nextProps) 处理。

Detail 组件中获取 ID,

const userId = this.props.match.params.userid;

以及在 Comment 中获取用户信息

const loginInfo = this.props.loginInfo;

数据请求

咱们在这里选择用 axios 网络请求,为了方便管理,将全部的 API 统一放在 /src/utils/api.jsx 中,利于后期维护。
没有使用 Fetch 是由于 Github API 只支持 XHR 跨域请求,Fetch 跨域请求会致使请求 request type 变成 option

数据更新

setState

由于此次的数据并不复杂,因此没有引入 MobX 或者 Redux 处理,数据更新全程使用 setState,不过因为 setState 是异步操做,因此,某些状况下,须要用到回调函数,以下

setState(
  { name: "Michael" },
  () => console.log(this.state.name)
);
// Michael

componentWillReceiveProps

上面提到过,经过路由参数获取下发数据,若是在 /user/lijundong 跳转到 /user/free-free 会出现路由改变,数据不刷新的状况,这是由于 componentDidMount() 只会执行一次,props 更新不会触发从新获取数据,这里可经过 componentWillReceiveProps() 解决。

componentWillReceiveProps() 会在每次 props 更新时触发,经过新参数从新获取数据列表。

componentWillReceiveProps(nextProps){
    const userId = nextProps.match.params.userid;
// 经过新参数获取数据
    Axios.get(url)
}

项目构建部署

项目开发结束,经过 npm run build 进行打包,打包完成后,生成的 /build/ 即咱们最终上线的版本,由于是先后端分离的项目,前端须要自起 Server,能够经过这两种方案进行部署

  • 使用 create-react-app 自带的 serve -s build 命令起 Server(我当前使用的方式)
  • 或者经过第三方工具 http-serveranywhere 等起 Server

服务开启后,能够正常访问就表明前端部分已经完成,暴露的端口供最后 Nginx 配置使用。

相关文章
相关标签/搜索