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 })=>(
  
    
      
    
 
)

技巧

使用对象展开符 ...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(
    
      
    
  )

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

  // 把渲染后的页面内容发送给客户端
  res.send(renderFullPage(html, preloadedState));
}

function renderFullPage(html, preloadedState){
  return `
    
    
      
        Redux Universal Example
      
      
        
${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

  • connect()

你可能感兴趣的:(Redux学习(高级))