Redux學(xué)習(xí)(高級(jí))

異步Action

一般情況下,每個(gè) API 請(qǐng)求都需要 dispatch 至少三種 action:

  • 一種通知 reducer 請(qǐng)求開始的 action
    對(duì)于這種 action,reducer 可能會(huì)切換一下 state 中的 isFetching 標(biāo)記。以此來告訴 UI 來顯示加載界面
  • 一種通知 reducer 請(qǐng)求成功的 action
    對(duì)于這種 action,reducer 可能會(huì)把接收到的新數(shù)據(jù)合并到 state 中,并重置 isFetching。UI 則會(huì)隱藏加載界面,并顯示接收到的數(shù)據(jù)。
  • 一種通知 reducer 請(qǐng)求失敗的 action
    對(duì)于這種 action,reducer 可能會(huì)重置 isFetching。另外,有些 reducer 會(huì)保存這些失敗信息,并在 UI 里顯示出來
{ type: 'FETCH_POSTS_REQUEST' }
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }

異步action 創(chuàng)建函數(shù)

// 第一個(gè)thunk action 創(chuàng)建函數(shù)
import fetch form 'cross-fetch'

export function fetchPosts(val){
  return function(dispatch){
    // 首次dispatch,Api 請(qǐng)求發(fā)起了
    //通知 reducer 請(qǐng)求開始的 action
    dispatch(requestPosts(val))
    // thunk middleware 調(diào)用的函數(shù)可以有返回值
    // 返回一個(gè)promise對(duì)象
    return fetch(`htttp: www.sdfusd.com/${val}`)
        .then(
            response=>response.json(),
            // 不要使用catch捕獲錯(cuò)誤
            error=>console.log(error)
            ).then(json=>{
            // 通知 reducer 請(qǐng)求成功的 action
            dispatch(receivePosts(val,json))
          })
        
  }
}

使用 applyMiddleware()

import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import { createStore, applyMiddleware } from 'redux'

const loggerMiddleware = createLogger()
const store = createStore(
  rootReducer,
  applyMiddleware(
    thunkMiddleware, // 允許我們dispatch函數(shù)
    loggerMiddleware
  )
)

//調(diào)用
 store.dispatch(fetchPosts('reactjs')).then(()=>console.log(store.getState()))

// 使用async函數(shù)優(yōu)雅實(shí)現(xiàn)

export const getProData=()=>{
  // 返回異步dispatch action創(chuàng)建函數(shù)
  return async dispatch=>{
    try{
        let result = await API.getProduction()
        dispatch({
          type: GETPROGEUDF,
          data: result
          })
      }catch(err){
        console.log(err)
      }
  }
}

// 頁面調(diào)用
import { getProData } from ''./actions'
this.props.getProData()

Middleware

middleware是位于action被發(fā)起之后,到達(dá)reducer之前的擴(kuò)展點(diǎn),可以用來進(jìn)行日志記錄,創(chuàng)建崩潰報(bào)告、調(diào)用異步接口等等
Middleware 接收了一個(gè) next() 的 dispatch 函數(shù),并返回一個(gè) dispatch 函數(shù),返回的函數(shù)會(huì)被作為下一個(gè) middleware 的 next()

搭配React Router

const Root = ({ store })=>(
  <Provider store={store}>
    <Router>
      <Route path="/" component={App} />
    </Router>
 </Provider>
)

技巧

使用對(duì)象展開符 ...spread 替代 Object.assign()

reducer 里不要使用 Object.assign(state, newData),應(yīng)該使用 Object.assign({}, state, newData)

服務(wù)端渲染

當(dāng)服務(wù)器收到請(qǐng)求時(shí),將組件渲染成HTML字符串,返回給客戶端
使用React.renderToString()

import { renderToString } from 'react-dom/server'
function handleRender(req, res) {
  // 創(chuàng)建新的 Redux store 實(shí)例
  const store = createStore(counterApp);

  // 把組件渲染成字符串
  const html = renderToString(
    <Provider store={store}>
      <App />
    </Provider>
  )

  // 從 store 中獲得初始 state
  const preloadedState = store.getState();

  // 把渲染后的頁面內(nèi)容發(fā)送給客戶端
  res.send(renderFullPage(html, preloadedState));
}

function renderFullPage(html, preloadedState){
  return `
    <!doctype html>
    <html>
      <head>
        <title>Redux Universal Example</title>
      </head>
      <body>
        <div id="root">${html}</div>
        <script>
          // window.__INITIAL_STATE__ 獲取 preloadedState
          window.__INITIAL_STATE__ = ${JSON.stringify(preloadedState)}
        </script>
        <script src="/static/bundle.js"></script>
      </body>
    </html>
`
}

API文檔

Redux
  • createStore(reducer,[preloaderdState, [enhancer]])
  • combineReducers(reducers)
  • applyMiddleware(...middlewares)
    -bindActionCreatores(actionCreators, dispatch)
  • compose(...functions)

store API

  • getState()
  • dispatch
  • subscribe(listener)
  • getReducer()
  • replaceReducer(nextReducer)

React Redux API

  • <Provider store={store}>
  • connect()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • http://gaearon.github.io/redux/index.html ,文檔在 http://rac...
    jacobbubu閱讀 80,415評(píng)論 35 198
  • 學(xué)習(xí)必備要點(diǎn): 首先弄明白,Redux在使用React開發(fā)應(yīng)用時(shí),起到什么作用——狀態(tài)集中管理 弄清楚Redux是...
    賀賀v5閱讀 9,069評(píng)論 10 58
  • 前言 本文 有配套視頻,可以酌情觀看。 文中內(nèi)容因各人理解不同,可能會(huì)有所偏差,歡迎朋友們聯(lián)系我討論。 文中所有內(nèi)...
    珍此良辰閱讀 12,189評(píng)論 23 111
  • #本文參加‘青春’大賽,本人保證本文為本人原創(chuàng),如有問題則與主辦方無關(guān),自愿放棄評(píng)優(yōu)評(píng)獎(jiǎng)資格 姓名:宋延婷 學(xué)校:...
    宋淺_baf4閱讀 520評(píng)論 0 28
  • 作者 悠悠我心 在我八九歲的時(shí)候,村里每家每戶都種西瓜,所以每到夜晚,...
    英若飄零閱讀 171評(píng)論 0 0

友情鏈接更多精彩內(nèi)容