前言
隨著react hooks
越來越火储矩,react-redux
也緊隨其后發(fā)布了7.1
(https://react-redux.js.org/api/hooks#using-hooks-in-a-react-redux-app)版本
首先是幾個API
- useSelector()
const result : any = useSelector(selector : Function, equalityFn? : Function)
主要作用:
從redux
的store
對象中提取數(shù)據(jù)(state
)肢扯。
注意:選擇器函數(shù)應(yīng)該是純函數(shù)蚕愤,因?yàn)樗赡茉谌我鈺r間點(diǎn)多次執(zhí)行揽趾。
import React from 'react'
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector(state => state.counter)
return <div>{counter}</div>
}
- useDispatch()
const dispatch = useDispatch()
返回Redux
store
中對dispatch
函數(shù)的引用呛踊。你可以根據(jù)需要使用它具则。
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>
)
}
將回調(diào)使用dispatch
傳遞給子組件時瞒窒,建議使用來進(jìn)行回調(diào)useCallback
,因?yàn)榉駝t乡洼,由于更改了引用崇裁,子組件可能會不必要地呈現(xiàn)。
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>
))
- useStore()
const store = useStore()
這個Hook
返回redux
<Provider>
組件的store
對象的引用束昵。
這個鉤子應(yīng)該不長被使用拔稳。useSelector
應(yīng)該作為你的首選。但是锹雏,有時候也很有用巴比。來看個例子:
import React from 'react'
import { useStore } from 'react-redux'
export const CounterComponent = ({ value }) => {
const store = useStore()
// 僅僅是個例子! 不要在你的應(yīng)用中這樣做.
// 如果store中的state改變,這個將不會自動更新
return <div>{store.getState()}</div>
}
dva中如何使用
dva
在dva@2.6.0[1]
的beta版本發(fā)布了這幾個API
,如果我們想使用他轻绞,首先安裝指定版本的
yarn add dva@2.6.0-beta.19
// or
npm install dva@2.6.0-beta.19
并且這樣使用
import { useSelector, useDispatch } from 'dva';
如果不想升級dva
版本的話我們需要安裝
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=>{
// 獲取數(shù)據(jù)
const {user,loading,dispatch} = props
// 發(fā)起請求
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
這個高階組件里定義了太多東西采记,這種寫法太惡心了。
如果太多數(shù)據(jù)從props
獲取的話政勃,connect
里堆了太多代碼
下面我們使用useDispatch
useSelector
優(yōu)化上面的代碼
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)
// 發(fā)起請求
useEffect(()=>{
dispatch({
type:'user/fetchUser',payload:{}
})
},[])
// 渲染頁面
if(loading) return <div>loading...</div>
return (
<div>{user.name}<div>
)
}
export default Home
使用useSelector
useDispatch
替代connect
關(guān)于
- 本文首發(fā)于使用useSelector useDispatch 替代connect