记录最近作的一个 demo,前端使用 React
,用 React Router
实现前端路由,Koa 2
搭建 API Server, 最后经过 Nginx
作请求转发。css
这是第一篇,主要介绍下前端代码的构建、React router
使用中遇到问题,以及前端开发完成后部署相关工做。html
GitCard 能够经过 GitHub 受权获取用户基本信息前端
/Comment
模块中能够发表评论,并删除本身的评论/Detail
模块中能够查看用户在 Github 上的基本信息(代码库,Follower、Following 以及更多开发的信息),你能够在这个基础上作更多有意思的事情,支持 Follow 和 Unfollow 操做,固然,你能够加上 Star 和 Unstar 操做,殊途同归。🈳️前端构建工具使用 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
布局并设置路由,将 Header
和 Container
包在 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
。
由于此次的数据并不复杂,因此没有引入 MobX 或者 Redux 处理,数据更新全程使用 setState
,不过因为 setState
是异步操做,因此,某些状况下,须要用到回调函数,以下
setState( { name: "Michael" }, () => console.log(this.state.name) ); // Michael
上面提到过,经过路由参数获取下发数据,若是在 /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,能够经过这两种方案进行部署
serve -s build
命令起 Server(我当前使用的方式)http-server
、anywhere
等起 Server服务开启后,能够正常访问就表明前端部分已经完成,暴露的端口供最后 Nginx 配置使用。