随着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