使用 React-Redux Hooks 和 React-Redux Connect() 的主要区别是啥?
Posted
技术标签:
【中文标题】使用 React-Redux Hooks 和 React-Redux Connect() 的主要区别是啥?【英文标题】:What is the main difference between using React-Redux Hooks and React-Redux Connect()?使用 React-Redux Hooks 和 React-Redux Connect() 的主要区别是什么? 【发布时间】:2020-01-21 10:47:18 【问题描述】:我即将使用 React-Redux 开始一个项目。对于 API 参考,有 Hooks 和 connect()。因为,Hooks 是连接 API 的替代品。使用钩子或连接到我的 React-Redux 项目有什么区别。
【问题讨论】:
【参考方案1】:在我的 React-Redux 项目中使用 hooks 和
connect
有什么区别
有两个主要区别:
Scopeconnect
可以与 React 类组件和函数组件一起使用,而钩子只能与函数组件一起使用。
性能与简单
使用钩子更简单。简单是有代价的:与connect
相比,您可以进行的性能调整更少。哪个更复杂:您将其称为传递配置选项(很少或很多)并取回connect
的“配置风格”。这种风格是您调用的 HOC,传入您的组件以将其重新包装。
主要配置选项之一是已经提到的mapStateToProps
函数。您不必使用它,但大多数情况下您会使用它。还有 4 个其他功能仅用于为您提供各种机会来提高您将使用 connect
环绕的组件的性能。函数调用:areStatesEqual
areStatePropsEqual
areOwnPropsEqual
areMergedPropsEqual
所有 4 个都是可选的。您可以作为connect
配置选项传入,可以不传入,也可以传入其中的一部分或全部,然后调整性能。值得注意的是,即使您没有传入任何参数,这些函数的默认实现(实际上是性能帮助器)也将应用,因此,您将获得比使用钩子更优化性能的包装组件对应的。
【讨论】:
非常真实,我发现我的挂钩组件比 HOC 组件慢一点。我想知道 React 正在做些什么来解决 Hook 基础设施中的这个问题,或者问题更多出在 React-Redux 上?性能调整是否可以通过 useSelector 函数以其他方式公开? @Eniola React 作者/维护者会更清楚,我感觉他们接受了现在钩子提供的优化选择更少。connect()
的好处是它同时接受函数和类组件,因此人们总是可以将 Redux 与没有钩子的函数组件一起使用。【参考方案2】:
React-Redux 内部使用React Context 将组件连接到商店。
connect()
函数将您的组件包装到另一个组件中,该组件连接到存储上下文并将所选状态作为道具转发给您的组件。
如果你打电话...
const YourConnectedComponent = connect(mapStateToProps)(YourComponent)`
...您可以想象包装器大致如下所示:
const YourConnectedComponent = props => (
<StoreContext.Consumer>
state => <YourComponent ...props ...mapStateToProps(state, props) />
</StoreContext.Consumer>
);
mapStateToProps
在这种情况下是您提供给connect()
的函数。
这是非常简化的,由于各种性能原因,它实际上看起来并不完全一样,但它适合演示一般概念。
useSelector
钩子也使用存储上下文,但没有为此创建一个组件。它直接返回选择状态供组件使用。它在内部使用useContext
,这是使用上下文的“钩子方式”。
useDispatch
只是将dispatch()
暴露给您的组件,以便它使用它来调度操作。
从技术上讲,无论您使用钩子还是connect()
,结果都差不多。
【讨论】:
【参考方案3】:connect
是一个High Order Component
,它的工作是提供一种将 Redux 的 store 连接到您的 components
的方法。 useSelector
和 useDispatch
是等效的 hooks
。只是做同样事情的另一种技术。
class Component extends React.Component
componentDidMount()
const fetchApi, arg = this.props
fetchApi(arg)
const mapDispatchToProps = dispatch =>(
fetchApi : arg => dispatch(fetchApi(arg))
)
const mapStateToProps = state =>(
arg : state.arg
)
export default connect(mapStateToProps, mapDispatchToProps)(Component)
现在相当于使用hooks
const Component = () =>
const dispatch = useDispatch()
const arg = useSelector(state => state.arg)
useEffect(() =>
dispatch(fetchApi(arg))
,[dispatch, arg])
两者的作用完全相同,只是将redux
连接到components
内部state
的方法不同。两者都使用 Redux 的上下文以在给定的 component
内公开 dispatch
和 state
【讨论】:
您将如何衡量性能差异? 非常简洁明了的示例,比文档要好得多。谢谢。【参考方案4】:钩子可以让你直接访问dispatch
和redux-state,而无需使用connect
连接组件,并且钩子只能在功能组件中使用
Connect
使我们能够将我们的组件(类或函数)与redux-store
链接,
您可以参考this链接中的react-redux
钩子文档。
它提供了不同的钩子,例如
useSelector
使用它我们可以访问redux store
useDispatch
返回 dispatch
函数,我们可以使用它来调度 redux 操作
一个组件的 redux 钩子的示例用法将是(只能在功能组件中使用)
functions Test()
const dispatch = useDispatch()
const count = useSelector(state => state.counter)
// If you want to dispatch a redux action using hooks then
// Assume a redux action called increaseCounter
return (
<>
<p>count</p>
<button onClick=() => dispatch(increaseCounter(count + 1))>
ClickMe!
</button></>)
如果你想使用 connect 来达到同样的效果(你可以在类或函数组件中使用它)
function Test()
return (
<>
<p>this.props.count</p>
<button onClick=() => this.props.increaseCounter(this.props.count+1)>Click Me!</button>
</>
);
const mapStateToProps = state =>
return
count: state.counter
;
;
const mapDispatchToProps = dispatch =>
return bindActionCreators( increaseCounter , dispatch);
;
export default connect(mapStateToProps, mapDispatchToProps)(Test)
【讨论】:
以上是关于使用 React-Redux Hooks 和 React-Redux Connect() 的主要区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章
只用两个自定义 Hooks 就能替代 React-Redux ?
React-redux 与 re-base-firebase。好主意?
如何在 React 中使用 hooks 实现 componentDidMount 以符合 EsLint 规则“react-hooks/exhaustive-deps”:“warn”?