記錄最近作的一個 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 配置使用。