使用 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 环绕的组件的性能。函数调用:areStatesEqualareStatePropsEqualareOwnPropsEqualareMergedPropsEqual 所有 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 的方法。 useSelectoruseDispatch 是等效的 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 内公开 dispatchstate

【讨论】:

您将如何衡量性能差异? 非常简洁明了的示例,比文档要好得多。谢谢。【参考方案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 - Redux Hooks的使用细节详解

如何在 React 中使用 hooks 实现 componentDidMount 以符合 EsLint 规则“re​​act-hooks/exhaustive-deps”:“warn”?

auto-redux,跟普通hooks一样使用redux。

React Redux with hooks - 身份验证和受保护的路由