前言
隨著react hooks 越來越火,react-redux 也緊隨其后發(fā)布了7.1 (https://react-redux./ap...
首先是幾個(gè)API
const result : any = useSelector(selector : Function, equalityFn? : Function)
主要作用: 從redux 的store 對(duì)象中提取數(shù)據(jù)(state )。
注意:選擇器函數(shù)應(yīng)該是純函數(shù),因?yàn)樗赡茉谌我鈺r(shí)間點(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>
}
const dispatch = useDispatch()
返回Redux store 中對(duì)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 傳遞給子組件時(shí),建議使用來進(jìn)行回調(diào)useCallback ,因?yàn)榉駝t,由于更改了引用,子組件可能會(huì)不必要地呈現(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>
))
const store = useStore()
這個(gè)Hook 返回redux <Provider> 組件的store 對(duì)象的引用。
這個(gè)鉤子應(yīng)該不長(zhǎng)被使用。useSelector 應(yīng)該作為你的首選。但是,有時(shí)候也很有用。來看個(gè)例子:
import React from 'react'
import { useStore } from 'react-redux'
export const CounterComponent = ({ value }) => {
const store = useStore()
// 僅僅是個(gè)例子! 不要在你的應(yīng)用中這樣做.
// 如果store中的state改變,這個(gè)將不會(huì)自動(dòng)更新
return <div>{store.getState()}</div>
}
dva中如何使用
dva 在dva@2.6.0[1] 的beta版本發(fā)布了這幾個(gè)API ,如果我們想使用他,首先安裝指定版本的
yarn add dva@2.6.0-beta.19
// or
npm install dva@2.6.0-beta.19
并且這樣使用
import { useSelector, useDispatch } from 'dva';
如果不想升級(jí)dva 版本的話我們需要安裝
yarn add react-redux@7.1.0
并且這樣使用
import { useSelector, useDispatch } from 'react-redux';
首先先看原始dva 的寫法 先定義一個(gè)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,
};
},
}
}
然后在頁(yè)面中使用
import {connect} from 'dva'
const Home = props=>{
// 獲取數(shù)據(jù)
const {user,loading,dispatch} = props
// 發(fā)起請(qǐng)求
useEffect(()=>{
dispatch({
type:'user/fetchUser',payload:{}
})
},[])
// 渲染頁(yè)面
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 這個(gè)高階組件里定義了太多東西,這種寫法太惡心了。 如果太多數(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ā)起請(qǐng)求
useEffect(()=>{
dispatch({
type:'user/fetchUser',payload:{}
})
},[])
// 渲染頁(yè)面
if(loading) return <div>loading...</div>
return (
<div>{user.name}<div>
)
}
export default Home
使用useSelector useDispatch 替代connect
關(guān)于
- 本文首發(fā)于使用useSelector useDispatch 替代connect
|