We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在v7.1中,react-redux加上了hooks,接下来我们就来看看新hooks,以及需要如何修改组件。 如果你还不清楚什么是hooks,建议阅读此文档。
签名:
const result : any = useSelector(selector : Function, equalityFn? : Function)
举例来说:
import { shallowEqual, useSelector } from 'react-redux' const count = useSelector(stoer => store.count, shallowEqual); // 第二个参数可选,也可以换成自定义的比较函数
用法很简单
const dispatch = useDispatch; dispatch({ type: 'action1' })
import React from 'react'; import { connect } from 'react-redux'; function componentWithConnect({ count, addCount }) { return ( <> <span>{count}</span> <button onClick={addCount}>点击</button> </> ); } const mapStateToProps = (store) => ({ count: store.count, }); const mapDispatch = (dispatch) => ({ addCount: () => dispatch({ type: 'addCount' }), }); export default connect(mapStateToProps, mapDispatch)(componentWithConnect);
import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; export default function componentWithHooks() { const { count } = useSelector(store => ({ count: store.count, })); const dispatch = useDispatch(); const addCount = () => dispatch({ type: 'addCount' }); return ( <> <span>{count}</span> <button onClick={addCount}>点击</button> </> ); }
在新组件中,我们去掉了connect,使用了useSelector和useDispatch两个hooks。这样就不用再从props传入,让逻辑更为内聚。(另外还有一个好处就是在React Devtools里也少了一层嵌套)
useSelector
useDispatch
可能有的同学会有疑问,useDispatch并没有完全代替mapDispatchToProps,为什么不加上useActions呢? 实际上在beta版本中,react-redux是带有useActions的,但在dan的建议下,去掉了这个api。为什么呢?其实只要自己模拟一下,你就能知道为什么了。
function someComponet() { // !!!!没有 useActions 这个api!!!! const actions = useActions((dispatch) => ({ action1: () => dispatch({ type: 'action1' }), action2: () => dispatch({ type: 'action2' }), })); useEffect(() => { actions.action1(); actions.action2(); }, [actions.action1, actions.action2]); }
看看为了发送一个dispatch,写了多少模板代码,要是有更多的action,useEffect的依赖列表就会变得更长。此外,在得到actions后,几乎是立即就又被解包了,在使用connect的情况下可能还是可以接受的,但在使用了hooks后,无疑是画蛇添足。 其实在过去,通过mapDispatchToProps将() => dispatch({ type: 'action1' })包装成一个actionCreator,是不是有过分迷恋这种『一行缩写』的嫌疑呢?更不要说这种缩写会让阅读代码的人搞不清数据流。 我们再来看如果直接使用useDispatch是怎么样的
mapDispatchToProps
() => dispatch({ type: 'action1' })
function someComponet() { const dispatch = useDispatch(); useEffect(() => { dispatch({ type: 'action1' }); dispatch({ type: 'action2' }); }, [dispatch]); }
是不是更简单,也更清晰了呢。
在很多情况下,useDispatch已经够用,但在一些复杂情况下,还是需要自定义hooks的。如要在多个组件间共享逻辑,自定义hooks是个不错的选择。
// complexActions.js const complexActions = () => { const dispatch = useDispatch(); dispatch({ type: 'actions1' }); dispatch({ type: 'actions2' }); someRequest().then(() => { dispatch({ type: 'actions3' }); }); // balbala... }; // componetA.js function componentA() { useEffect(() => { complexActions(); }, [complexActions]); return (...); } // componetB.js function componentB() { useEffect(() => { complexActions(); }, [complexActions]); return (...); }
触发dispatch后,useSelector被触发(因为useSelector是使用useEffect实现,useEffect的依赖就有store),当发现前后两次state不一样时,会触发重渲染。此时的问题是当不相关的值被修改,本组件仍然会重渲染。可以使用reselect来减少这种情况,具体怎么做,可以参考官方文档。 另外,connect也会对props做一次浅比较,防止重渲染。所以去掉connect之后,就需要使用React.memo去做了。
React.memo
import React from 'react'; function componentA(props) { return <>...</> } export default React.memo(componentA);
The text was updated successfully, but these errors were encountered:
—_—
Sorry, something went wrong.
No branches or pull requests
在v7.1中,react-redux加上了hooks,接下来我们就来看看新hooks,以及需要如何修改组件。
如果你还不清楚什么是hooks,建议阅读此文档。
hooks
useSelector
签名:
举例来说:
useDispatch
用法很简单
使用connect的写法
换成hooks的写法
在新组件中,我们去掉了connect,使用了
useSelector
和useDispatch
两个hooks。这样就不用再从props传入,让逻辑更为内聚。(另外还有一个好处就是在React Devtools里也少了一层嵌套)消失的useActions?
可能有的同学会有疑问,useDispatch并没有完全代替mapDispatchToProps,为什么不加上useActions呢?
实际上在beta版本中,react-redux是带有useActions的,但在dan的建议下,去掉了这个api。为什么呢?其实只要自己模拟一下,你就能知道为什么了。
看看为了发送一个dispatch,写了多少模板代码,要是有更多的action,useEffect的依赖列表就会变得更长。此外,在得到actions后,几乎是立即就又被解包了,在使用connect的情况下可能还是可以接受的,但在使用了hooks后,无疑是画蛇添足。
其实在过去,通过
mapDispatchToProps
将() => dispatch({ type: 'action1' })
包装成一个actionCreator,是不是有过分迷恋这种『一行缩写』的嫌疑呢?更不要说这种缩写会让阅读代码的人搞不清数据流。我们再来看如果直接使用useDispatch是怎么样的
是不是更简单,也更清晰了呢。
自定义hooks
在很多情况下,useDispatch已经够用,但在一些复杂情况下,还是需要自定义hooks的。如要在多个组件间共享逻辑,自定义hooks是个不错的选择。
性能优化建议
触发dispatch后,useSelector被触发(因为useSelector是使用useEffect实现,useEffect的依赖就有store),当发现前后两次state不一样时,会触发重渲染。此时的问题是当不相关的值被修改,本组件仍然会重渲染。可以使用reselect来减少这种情况,具体怎么做,可以参考官方文档。
另外,connect也会对props做一次浅比较,防止重渲染。所以去掉connect之后,就需要使用
React.memo
去做了。参考
The text was updated successfully, but these errors were encountered: