隨着react hooks
愈來愈火,react-redux
也緊隨其後發佈了7.1
(https://react-redux.js.org/ap...javascript
首先是幾個API
html
const result : any = useSelector(selector : Function, equalityFn? : Function)
主要做用:
從redux
的store
對象中提取數據(state
)。java
注意:選擇器函數應該是純函數,由於它可能在任意時間點屢次執行。
import React from 'react' import { useSelector } from 'react-redux' export const CounterComponent = () => { const counter = useSelector(state => state.counter) return <div>{counter}</div> }
const dispatch = useDispatch()
返回Redux
store
中對dispatch
函數的引用。你能夠根據須要使用它。react
import React from 'react' import { useDispatch } from 'react-redux' export const CounterComponent = ({ value }) => { const dispatch = useDispatch() return ( <div> <span>{value}</span> <button onClick={() => dispatch({ type: 'increment-counter' })}> Increment counter </button> </div> ) }
將回調使用dispatch
傳遞給子組件時,建議使用來進行回調useCallback
,由於不然,因爲更改了引用,子組件可能會沒必要要地呈現。npm
import React, { useCallback } from 'react' import { useDispatch } from 'react-redux' export const CounterComponent = ({ value }) => { const dispatch = useDispatch() const incrementCounter = useCallback( () => dispatch({ type: 'increment-counter' }), [dispatch] ) return ( <div> <span>{value}</span> <MyIncrementButton onIncrement={incrementCounter} /> </div> ) } export const MyIncrementButton = React.memo(({ onIncrement }) => ( <button onClick={onIncrement}>Increment counter</button> ))
const store = useStore()
這個Hook
返回redux
<Provider>
組件的store
對象的引用。redux
這個鉤子應該不長被使用。useSelector
應該做爲你的首選。可是,有時候也頗有用。來看個例子:api
import React from 'react' import { useStore } from 'react-redux' export const CounterComponent = ({ value }) => { const store = useStore() // 僅僅是個例子! 不要在你的應用中這樣作. // 若是store中的state改變,這個將不會自動更新 return <div>{store.getState()}</div> }
dva
在dva@2.6.0[1]
的beta版本發佈了這幾個API
,若是咱們想使用他,首先安裝指定版本的bash
yarn add dva@2.6.0-beta.19 // or npm install dva@2.6.0-beta.19
而且這樣使用app
import { useSelector, useDispatch } from 'dva';
若是不想升級dva
版本的話咱們須要安裝ide
yarn add react-redux@7.1.0
而且這樣使用
import { useSelector, useDispatch } from 'react-redux';
首先先看原始dva
的寫法
先定義一個user model
// 1.user.js ==>model export default { namespace: 'user', state: { userInfo:null, }, effects: { *fetchUser({paylaod},{call,put}){ const res = yield(api,payload) yield put({ type: 'save', payload: { userInfo:res }, }); } }, reducers:{ save(state, { payload }) { return { ...state, ...payload, }; }, } }
而後在頁面中使用
import {connect} from 'dva' const Home = props=>{ // 獲取數據 const {user,loading,dispatch} = props // 發起請求 useEffect(()=>{ dispatch({ type:'user/fetchUser',payload:{} }) },[]) // 渲染頁面 if(loading) return <div>loading...</div> return ( <div>{user.name}<div> ) } export default connect(({loading,user})=>({ loading:loading.effects['user/fetchUser'], user:user.userInfo }))(Home)
connect
這個高階組件裏定義了太多東西,這種寫法太噁心了。
若是太多數據從props
獲取的話,connect
裏堆了太多代碼
下面咱們使用useDispatch
useSelector
優化上面的代碼
import {useDispatch,useSelector} from 'dva' const Home = props=>{ const dispatch = useDispatch() const loadingEffect = useSelector(state =>state.loading); const loading = loadingEffect.effects['user/fetchUser']; const user = useSelector(state=>state.user.userInfo) // 發起請求 useEffect(()=>{ dispatch({ type:'user/fetchUser',payload:{} }) },[]) // 渲染頁面 if(loading) return <div>loading...</div> return ( <div>{user.name}<div> ) } export default Home
使用useSelector
useDispatch
替代connect