react服務端渲染框架next.js踩坑筆記
正文共:11917字13圖預計閱讀時間:30分鐘
按照領導的要求,以後前端web項目一律要換成React.js的技術棧,作為一個有點ReactNative踩坑經驗的web前端開發,項目經理讓我今天給公司同事做一次分享...說實話講得不是很好,後續還要加油!準備了一個文檔,在此放到微信公眾號上來,避免以後再踩坑~
說明
React作為Facebook 內部開發 Instagram 的項目中,是一個用來構建用戶界面的優秀 JS 庫,於 2013 年 5 月開源。作為前端的三大框架之一,React的應用可以說是非常的廣泛。這裡講一個react服務端渲染的框架-next.js踩坑過程。
技術棧
大綱
按照以下思路來寫:
大綱.png
react基本語法
react基本語法參照react文檔,這裡發放一個鏈接https://doc.react-china.org/。
以下是React重要的部分
JSX – 允許我們編寫類似HTML的語法,轉換為JavaScript對象;
虛擬DOM – 實際DOM的JavaScript表示;
React.Component – 創建新組件的方式;
ReactDOM.render – 用於將模板轉為 HTML 語言,並插入指定的 DOM 節點;
state – 組件的內部數據存儲(對象),類似理解vue的data;
constructor(this.state) – 建立組件初始 state(狀態) 的方式;
setState – 一種輔助方法,用於更新組件的 state(狀態) 並重新渲染,類似微信小程序;
props – 從父組件傳遞給子組件的數據;
className - 節點的class,css標記
style jsx樣式控制
jsx語法
直接寫在 JavaScript 語言之中,不加任何引號,它允許 HTML 與 JavaScript 的混寫。
上面代碼體現了 JSX 的基本語法規則:遇到 HTML 標籤(以
頁面渲染效果
組件及組件傳值
渲染頁面效果
React之ref(獲取真實的DOM節點)
同vue的ref作用一樣,組件並不是真實的DOM節點,而是存在於內存之中的一種數據結構,叫做虛擬 DOM。
只有當它插入文檔以後,才會變成真實的 DOM 。根據 React的設計,所有的DOM 變動,都先在虛擬 DOM上發生,然後再將實際發生變動的部分,反映在真實 DOM上,這種演算法叫做 DOM diff ,它可以極大提高網頁的性能表現。
有時需要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性。
在這裡需要注意的是:
React的事件中如果不用剪頭函數,那就要用bind來綁定this,否則需要在constructor構造函數里調用this.handleClick = this.handleClick.bind(this),這裡建議用onClick=。
由於 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以後,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之後,才會讀取 this.refs.[refName] 屬性。
GIF
demo3.gif
React之this.state以及點擊事件
React中的state就相當於vue里的data數據存儲,而小程序的this.setData就和React的this.setState類似。
上面代碼是一個 LikeButton 組件,它的 constructor 方法(或者直接state聲明)用於定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以後,自動調用 this.render 方法,再次渲染組件。
由於 this.props 和 this.state 都用於描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著用戶互動而產生變化的特性。
GIF
demo4.gif
利用input的onChange事件實現簡單的雙向綁定
vue裡面v-model一鍵實現的事情React沒有,我們可以利用input組件的onChange事件來簡單實現它,直接上代碼。
GIF
demo5.gif
組件的生命周期
組件的生命周期.png
一個React組件的生命周期分為三個部分:掛載期(Mounting)、存在更新期(Updating)和銷毀時(Unmounting)。
Mounting:已插入真實 DOM
當一個組件實例被創建並且插入到DOM中,以下鉤子將被調用 constructor()
繼承react的props,和設置state的初始化。
Updating:當組件的props和state發生改變時,重新渲染頁面是調用的。
Unmounting:組件從DOM中移動時調用的。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
事件
onClick-點擊事件
onSubmit-表單提交事件,可以配合antdesign的表單校驗
onChange-input框數據變化,可實現數據的雙向綁定(react里沒有vue的v-modal)
style jsx
我們可以通過普通樣式(className)和行內樣式(LineStyle)控制React組件的樣式:
使用className設置樣式(與CSS的選擇器相同
2018072415323991173447.png
為什麼要用next
Next.js是一個基於React的一個服務端渲染簡約框架。它使用React語法,可以很好的實現代碼的模塊化,有利於代碼的開發和維護。
默認服務端渲染模式,以文件系統為基礎的客戶端路由,類似nuxt.js;
與nuxt.js相同,pages文件目錄即路由;
以webpack的熱替換為基礎的開發環境(npm run dev);
next創建的項目目錄結構
next創建的項目目錄結構.png
代碼自動分割
你所聲明的每個 import命令所導入的文件會只會與相關頁面進行綁定並提供服務,頁面不會載入不需要的代碼。
next路由
默認從 pages 目錄下取頁面進行渲染返回給前端展示,路由可以使用Link(無刷新頁面)或者a標籤(刷新頁面)
接收參數:getInitialProps方法context參數或者,同時在getInitialProps 裡面獲取數據,服務端渲染會提前執行這個方法獲取數據渲染到模板,這裡用到axios庫,前後端都可以使用
數據請求-axios配置
axios具有以下幾個特點:
既可以在服務端使用又可以在瀏覽器端使用;
支持 Promise API(async await,解決地獄回調);
攔截請求和響應(401跳轉登錄等操作);
轉換請求數據和響應數據;
自動轉換 JSON 數據。
以下為axios配置代碼:
使用時在頁面引入axios配置文件axios.js,具體的axios配置可以參考link-axios文檔。https://www.kancloud.cn/yunye/axios/234845
數據請求-開發環境代理
前後端分離以後,前端最常見的一個問題就是跨域,之前的om項目基於nuxt可以配置proxy,在next.js里需要用到express和http-proxy-middleware在服務端(node)端做一層轉發,代碼配置如下:
配置完server.js後還需要在packge.json中配置啟動腳本:
注意上線後需要在ngnix里配置反向代理,就不存在跨域的問題。
在next.js里使用ant design
babel配置
引用ant design組件,需要用到ant design什麼組件按照自己需要引用即可,各個組件使用方法參考ant design的link-官方文檔
部署一個next.js項目
Next.js 項目的部署,需要一個 Node.js的伺服器。
在開發環境伺服器的入口文件就使用上文中提到的 server.js,在 server.js 里添加了針對部署環境的選擇,代碼如下
為了區分部署環境,我們需要在 package.json 中修改 script 屬性如下:
其中,build 命令是用於打包項目,start 命令是用於生產環境部署,devdev 命令是用於本地開發,PORT為啟動埠。
總結
只要熟悉React開發,上手一個Next項目很容易,Next 讓前端項目開發效率更高。在此需要注意以下幾個點:
增加第三方npm包必須加上--save關鍵字,會pakage.json文件里加入依賴包;
組件名稱必須以大寫字母開頭,如MyHeader,不然程序運行會報錯;
React的事件中如果不用剪頭函數,那就要用bind來綁定this,否則需要在constructor構造函數里調用this.handleClick = this.handleClick.bind(this),這裡建議用onClick=;
jsx style控制組件樣式時注意要在組件內部,並且要用
以下為近期輸出的文章
喜歡記得來一個
TAG:長大幫 |