Skip to content
New issue

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

关于react hook 返回组件模式的讨论 #68

Open
Topppy opened this issue May 18, 2022 · 0 comments
Open

关于react hook 返回组件模式的讨论 #68

Topppy opened this issue May 18, 2022 · 0 comments
Milestone

Comments

@Topppy
Copy link
Owner

Topppy commented May 18, 2022

hook return component

首先在react中:

  • React Component == UI
  • React Hook == behavior/Logic

hook的设计之初的几个点:

  • 解决“reuse stateful logic between components”的问题
  • 允许按照功能划分复杂逻辑,而不是按照生命周期混在一起

在hook出现之前,我们只可以将UI抽离成可以复用的component,但是相似的state和loggic还需要写很多遍。hook之后我们解决了这个问题。

通常在业务中,UI和behavior是耦合的,强相关的,比如isOpen和closeModal通常跟Modal 组件强相关联,总是成对出现。
有时候,父组件需要使用behavior数据

  • 那么behavior数据应当被提升到父组件吗?即使behavior数据跟子组件强耦合。
  • 例如:父组件创建了一个需要知道何时关闭的Modal组件以便取消请求。那么父组件只能管理isOpen状态吗?
  • behavior和component的绑定代码,还需要一遍遍重复吗?

返回组件的模式可能是一个优雅的解决方案。【1】,在hook中,不仅抽离了state和逻辑,组件以及组件和hook的绑定也都放在hook中,hook 返回{ state, method, component }

就像这样:

import useMenu from './useMenu'

export const Demo = () => {
// 这里返回的Menu是一个组件,openMenu, closeMenu 是方法,isOpen是state
const { Menu, openMenu, closeMenu, isOpen } = useMenu()

return (
    <React.Fragment>
      <Button onClick={openMenu} variant="contained">
        Example Menu open ?:{ isOpen ? 'yes' : 'no'}
      </Button>

      <Menu />
    </React.Fragment>
  );
}

熟悉hook的一定可以注意到一点,Demo每次执行,useMenu都会执行一遍,返回新的component,这显然是不太完美的。

一个解决方案是:

  • 返回Component静态定义而不是Component实例
  • Returned Compoent和 hook 之间使用Context来共享数据和组件实例引用

【2】Third iteration: Return statically defined component from hooks

参考文章

【1】New React Hooks Pattern? Return a Component

【2】React Design Patterns: Return Component From Hooks

【3】React Hooks: Compound Components

@Topppy Topppy added this to the publish milestone Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant