前言
隨著react hooks 越來越火,react-redux 也緊隨其后發(fā)布了7.1 (https://react-redux./ap...
首先是幾個API
const result : any = useSelector(selector : Function, equalityFn? : Function)
主要作用: 從redux 的store 對象中提取數據(state )。
注意:選擇器函數應該是純函數,因為它可能在任意時間點多次執(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 中對dispatch 函數的引用。你可以根據需要使用它。
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 ,因為否則,由于更改了引用,子組件可能會不必要地呈現(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()
這個Hook 返回redux <Provider> 組件的store 對象的引用。
這個鉤子應該不長被使用。useSelector 應該作為你的首選。但是,有時候也很有用。來看個例子:
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 在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=>{
// 獲取數據
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 這個高階組件里定義了太多東西,這種寫法太惡心了。 如果太多數據從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
關于
- 本文首發(fā)于使用useSelector useDispatch 替代connect
|