Redux学习(高级)

异步Action

一般情况下,每个 API 请求都需要 dispatch 至少三种 action:

  • 一种通知 reducer 请求开始的 action
    对于这种 action,reducer 可能会切换一下 state 中的 isFetching 标记。以此来告诉 UI 来显示加载界面
  • 一种通知 reducer 请求成功的 action
    对于这种 action,reducer 可能会把接收到的新数据合并到 state 中,并重置 isFetching。UI 则会隐藏加载界面,并显示接收到的数据。
  • 一种通知 reducer 请求失败的 action
    对于这种 action,reducer 可能会重置 isFetching。另外,有些 reducer 会保存这些失败信息,并在 UI 里显示出来
{ type: 'FETCH_POSTS_REQUEST' }
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }

异步action 创建函数

// 第一个thunk action 创建函数
import fetch form 'cross-fetch'

export function fetchPosts(val){
  return function(dispatch){
    // 首次dispatch,Api 请求发起了
    //通知 reducer 请求开始的 action
    dispatch(requestPosts(val))
    // thunk middleware 调用的函数可以有返回值
    // 返回一个promise对象
    return fetch(`htttp: www.sdfusd.com/${val}`)
        .then(
            response=>response.json(),
            // 不要使用catch捕获错误
            error=>console.log(error)
            ).then(json=>{
            // 通知 reducer 请求成功的 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函数
    loggerMiddleware
  )
)

//调用
 store.dispatch(fetchPosts('reactjs')).then(()=>console.log(store.getState()))

// 使用async函数优雅实现

export const getProData=()=>{
  // 返回异步dispatch action创建函数
  return async dispatch=>{
    try{
        let result = await API.getProduction()
        dispatch({
          type: GETPROGEUDF,
          data: result
          })
      }catch(err){
        console.log(err)
      }
  }
}

// 页面调用
import { getProData } from ''./actions'
this.props.getProData()

Middleware

middleware是位于action被发起之后,到达reducer之前的扩展点,可以用来进行日志记录,创建崩溃报告、调用异步接口等等
Middleware 接收了一个 next() 的 dispatch 函数,并返回一个 dispatch 函数,返回的函数会被作为下一个 middleware 的 next()

搭配React Router

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

技巧

使用对象展开符 ...spread 替代 Object.assign()

reducer 里不要使用 Object.assign(state, newData),应该使用 Object.assign({}, state, newData)

服务端渲染

当服务器收到请求时,将组件渲染成HTML字符串,返回给客户端
使用React.renderToString()

import { renderToString } from 'react-dom/server'
function handleRender(req, res) {
  // 创建新的 Redux store 实例
  const store = createStore(counterApp);

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

  // 从 store 中获得初始 state
  const preloadedState = store.getState();

  // 把渲染后的页面内容发送给客户端
  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()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • http://gaearon.github.io/redux/index.html ,文档在 http://rac...
    jacobbubu阅读 79,900评论 35 198
  • 使用redux+react已有一段时间,刚开始使用并未深入了解其源码,最近静下心细读源码,感触颇深~ 本文主要包含...
    字节跳动技术团队阅读 1,457评论 0 5
  • 学习必备要点: 首先弄明白,Redux在使用React开发应用时,起到什么作用——状态集中管理 弄清楚Redux是...
    贺贺v5阅读 8,877评论 10 58
  • 前言 本文 有配套视频,可以酌情观看。 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我讨论。 文中所有内...
    珍此良辰阅读 11,894评论 23 111
  • #本文参加‘青春’大赛,本人保证本文为本人原创,如有问题则与主办方无关,自愿放弃评优评奖资格 姓名:宋延婷 学校:...
    宋浅_baf4阅读 445评论 0 28