react與redux通訊之hook

react和redux創建通訊的方式

有2種方案:javascript

  • 老方案connect
  • 新方案hook

老方案connect

曾經,咱們會使用connect創建react和redux的通訊,例如,在一個class寫法的組件中:java

import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import globalAction from 'actions/global'
@connect(
    // 取得reducer中的state
    state => ({global: state.global}), 
    // 取得action
    dispatch => bindActionCreators({ globalAction }, dispatch)
)
class Component extends React.Component {
    componentDidMount() {
        // 從props中讀取reducer和action
        const {global, globalAction} = this.props
        globalAction()
        console.log(global)
    }
    render() {
        return <div />
    }
}

對於用習慣了class組件的開發者來講,這種寫法爛熟於心了。可是,無論你多喜歡這種模式,仍是得學習react hook。react

新方案hook

隨着react16.8的發佈,hook功能正式投入使用。
將react的class組件轉換成函數式組件,想必你已經看過官網的demo了,若是沒看,回頭看一下也不晚。那麼,若是咱們使用了hook,又該如何跟redux通訊呢?
針對於這個問題,業界有人提供了一個取代react-redux的新插件redux-react-hook。
redux-react-hook使用了react提供的Context(上下文)功能,給頂層組件Provide傳入了store對象,綁定到上下文。
使用了redux-react-hook以後,上面的demo就變成了下面這種寫法:編程

import React, { useEffect } from 'react'
import { useDispatch, useMappedState, StoreContext } from 'redux-react-hook'
import globalAction from 'actions/global'
function Component {
    // 獲取上下文的store對象
    const store = useContext(StoreContext)
    // 從store中讀取reducer
    const {global} = store
    // 從store中讀取dispatch
    const dispatch = useDispatch()
        
    useEffect(() => {
        dispatch(globalAction())
        console.log(global)
    }, [global, dispatch, globalAction])
    
    render() {
        return <div />
    }
}

修改後的demo使用到了redux-react-hook提供的其中2個API,StoreContext和useDispatch,其次,還能夠使用useMappedState來獲取reducer中的狀態。redux

const mapState = useCallback(
    state => ({
        global: state.global
    }),
    [],
);
const { global } = useMappedState(mapState);

redux-react-hook

簡單介紹寫3個API,StoreContext,useDispatch,useMappedState。app

StoreContext

React提供的createContext建立上下文,返回該對象。ide

import { createContext } from 'react';
// 建立context
const StoreContext = createContext<TStore | null>(null)
return StoreContext

useDispatch

讀取StoreContext,返回dispatch。函數式編程

function useDispatch(): Dispatch<TAction> {
    // 從上下文讀取store
    const store = useContext(StoreContext);
    if (!store) {
      // store不存在,拋出異常
      throw new MissingProviderError();
    }
    return store.dispatch;
  }
return useDispatch

useMappedState

useMappedState跟其餘2個API不太同樣,它是一個自定義的hook,用來訂閱reducer裏的狀態。函數

總結

hook式的寫法到底是好是壞,暫且沒法分辨,就像有人以爲函數式編程很好,但有人以爲函數式編程使得代碼難於維護。
能夠預見的是,當你使用了hook,會在項目中逐漸把class消滅,最後跟class語法糖告別,迴歸函數的世界。學習

相關文章
相關標籤/搜索