react全家桶快餐進食指南

emmmmm。。。。。。。。。。css

若是有什麼說的不對的地方,歡迎評論告知。html

=3333333=前端

先從最基礎的react提及吧,目前框架都屬於組件化的,可是更主要的目的是爲了讓前端圍繞着數據邏輯來作頁面而並不是原先的去操做dom的思想,三大框架目前都是往一個方向去。不過相比其餘,react主打是diff算法處理dom,因此掌握他的生命週期去處理好數據纔是咱們最初應該學習的東西。node

react

最經常使用的就是react.Component
談一下他的生命週期吧。
假如我頁面有一個首頁,咱們如今要作頂部的導航欄,那麼咱們如今去寫一個頂部導航的組件。
假設這個頂部的導航,每一個人權限不一樣,看到的東西不同,那麼這個導航是經過請求數據來實現的。react

來,先熟悉git

生命週期。

掛載時期會執行的(能夠理解爲這個組件丟到頁面時候會執行,而且只執行一次的)。github

constructor() // 構造函數,通常我會在這裏去定當前組件的state初始化

componentWillMount() // 掛載以前,在17以後更名下面一條

UNSAFE_componentWillMount() // 上面掛載前立刻要更改的名字。
//這個是惟一會在服務端調用的生命週期鉤子,在這裏設置一些東西不會致使組件從新渲染,
//因此這裏最好不要隨意進行一些組件須要數據的請求。

render() // 這個組件須要輸出的東西,按道理來講都是一些jsx之類的,
//若是你輸出的是字符串和數字,則會變成text node, 
//若是輸出的是布爾值的false,或者null,就會不進行渲染。

componentDidMount() // 這裏就是組件掛載時候最後觸發的一個生命週期了。
// 由於這個裏面請求數據會讓組件從新渲染,因此通常數據放在這裏進行請求。

而後這個組件由於數據變化也會從新渲染,一種是props改變的時候(或者父組件從新渲染的時候),一種是本身的state改變的時候。web

props改變的時候會執行的生命週期算法

UNSAFE_componentWillReceiveProps(nextProps) // 這個生命週期在17版以前叫componentWillReceiveProps
// 通常是在父組件更新的時候,或者props改變的時候會觸發的,用來根據props更改而改本組件state用的
// 官方目前推薦用下一條去替換他

static getDerivedStateFromProps(nextProps, prevState) // 接收到新的props或者父組件從新渲染的時候,都會調用。
// 若是你只想處理變化,就要比較新舊值
// 做用跟上面一條是同樣的,props改變時候要改state就在這裏作

shouldComponentUpdate(nextProps, nextState) // 這裏能夠經過返回false,來阻止從新渲染
// 默認爲true,若shouldComponentUpdate()返回false,
//然後UNSAFE_componentWillUpdate(),render(), 和 componentDidUpdate()將不會被調用

UNSAFE_componentWillUpdate() // 17版之前叫componentWillUpdate
// 在收到新的state或者props的時候,渲染前被當即調用
//不要在這裏setState,不要在這裏setState,不要在這裏setState,

render() // 固然少不了輸出須要顯示的東西啦

getSnapshotBeforeUpdate() // 在最新的渲染輸出提交給DOM前將會當即調用
// 爲了支持異步渲染,若是在componentWillUpdate處理的一些事情,可能會有延遲滯後
// 這一輩子命週期返回的任何值將會 做爲參數被傳遞給componentDidUpdate()。

componentDidUpdate(prevProps, prevState) // 終於說到最後一個了,我擦啦
// 更新發生後當即被調用
// 這也是一個適合發送請求的地方,要是你對比了當前屬性和以前屬性(例如,若是屬性沒有改變那麼請求也就不必了),否則就循環給你看,嘿嘿嘿嘿嘿嘿

而後就是state更改的時候了,懶得打了,就是上面props更改時候的一些生命週期去掉UNSAFE_componentWillReceiveProps(nextProps)或者static getDerivedStateFromProps(nextProps, prevState),直接從shouldComponentUpdate開始。redux

最後組件準備被移除的時候

componentWillUnmount()
// 在組件被卸載和銷燬以前馬上調用。能夠在該方法裏處理任何須要的清理工做
// 例如解綁定時器,取消網絡請求,清理任何在componentDidMount環節建立的DOM元素。

捕捉錯誤的生命週期

componentDidCatch(error, info)
// 打印它們之下組件裏的錯誤,不能捕捉它本身內部的錯誤。
// 在這裏是用來處理錯誤的,不要嘗試用這個去處理數據

好了,生命週期大體就是這些,估計看完也困了。
咱們假如要作一個頂部導航,那麼(敲黑板)重點就在於這個組件怎麼請求,請求完了啥時候往裏面丟,頁面怎麼處理之類的。

其實總結起來也比較簡單,步驟以下

  1. constructor() 定初始化的state,裏面有一個咱們須要循環展現出來的list用來儲存導航
  2. render() 裏面寫好循環state裏面的list等展現效果
  3. componentDidMount() 根據當前用戶的一些信息去請求數據,而且處理完setState塞入list裏面
  4. shouldComponentUpdate() 若是他的父組件會更新,可是他不須要作過多的重複渲染,則在這裏判斷新舊值,考慮是否要從新渲染

另外有的小夥伴說,React.PureComponent能夠幫你處理一些 shouldComponentUpate()新舊值的判斷是否要從新渲染,不過這個只會對對象進行淺對比
若是對象包含複雜的數據結構,那麼可能會致使他沒法渲染出你要的最新的數據,React.PureComponent 的 shouldComponentUpate() 會忽略整個組件的子級。請確保全部的子級組件也是」Pure」的。


關於redux的數據流

說簡單一點,其實就是

  1. 我往項目根部建立一個store(儲存數據的東西)
  2. 觸發action
  3. action告訴reducer我要改數據了!
  4. reducer改完了數據頁面也同時拿到了

action => reducer => store

不過由於redux不但願有一些反作用的數據產生,因此咱們要在這裏面請求數據,就須要一些中間件。
目前比較大衆的有倆。
redux-saga和redux-thunk

先大體介紹一下

redux-thunk

說簡單一些,就是讓action中能夠請求異步操做,請求到了數據再執行reducer存入store裏面。

引入方法

import thunkMiddleware from 'redux-thunk'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import { Reduces } from './store/index.js' // 引入全部的reduces

const store = createStore(
  Reduces,
  applyMiddleware(
    thunkMiddleware // 容許 dispatch() 函數
  )
)

<Provider store={store}> // 丟到裏面去
    <Router>
    </Router>
 </Provider>

而後在action裏面,就能夠

/**
   * 獲取用戶訂單信息
   * @param {String} type 用戶訂單的請求類型
   * @return {dispatch} dispatch 返回調用新的action方法
   */
  getUserOrderList(type) {
    return dispatch => {
    // 這個OrderModel是我本身項目全部訂單請求都放在裏面的,其實就至關與寫一個fetch,而後then的處理他
      return OrderModel.orderlist({
        status: type
      }).then(response => {
        // 這裏在存入store裏面去,這裏通常我會寫一個公用的dispatch的方法進行丟入
      })
    }
  }

而後用dva的朋友通常用的都是

redux-saga

這個其實我瞭解的並不深,就拿官網的事例來用一下

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

// worker Saga : 將在 USER_FETCH_REQUESTED action 被 dispatch 時調用
function* fetchUser(action) {
   try {
       // call這裏進行請求數據,拿到的數據丟到user裏面
      const user = yield call(Api.fetchUser, action.payload.userId);
      // 開始匹配type,進行數據更改在這裏
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

這裏放上兩個文檔供參考

redux-saga
redux-thunk

bug

通常玩react最容易遇到的坑,就是如何處理好數據,搭配生命週期,剛開始可能會由於沒處理好數據,致使組件無內容報錯,也有循環不加key等。

感受報錯最多的可能性應該是這個key了。
當循環的時候,或者使用table表單的時候,特別是antd裏面的table,要仔細看文檔,須要key的時候必定要加上。

route

route目前用的比較多的是兩種
BrowserRouter和HashRouter

HashRouter

這個就比較醜了,可是路由都在前端,全部的頁面都是用#後面帶上一些東西,前端本身作管理就行了。
HashRouter 使用 URL 的 hash (例如:window.location.hash) 來保持 UI 和 URL 的同步。
不過像描點就不要想啦。

import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>

BrowserRouter

這個就是使用 HTML5 提供的 history API 來處理路由,全部的頁面都是真實路徑,須要後端配置全部請求頁面都指向咱們的主頁面。

import { BrowserRouter } from 'react-router-dom'

<BrowserRouter>
  <App/>
</BrowserRouter>

跳轉路由直接頁面裏面跳轉,能夠用下面的方法

import { Link } from 'react-router-dom'

<Link to="/about">關於</Link>

若是是在js裏面想跳轉,則

this.props.history.push() // 或者replace,過着go()啥的

就能夠進行跳轉了,不過組件裏面要拿到父組件的props須要繼承一下

好比

<子組件 {...this.props}></子組件>

這樣就能夠把父組件的props所有丟到子組件裏面去 =3=

最後把項目的一些須要的文檔整理了一下

相關文章
相關標籤/搜索