question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

背景

在 hox v1 中,我们的实现方案是在应用的 React 组件树之外,额外创建一个组件树,以存储 hox 中的 model。然而,这种方案渐渐显露出较多的弊端:

  • 对渲染环境的要求比较苛刻,强依赖 react-dom,SSR、RN、小程序都无法使用(#10 #11 #13)。即便可以通过 custom renderer 解决,但是又会导致包体积较大(#26)。
  • 无法和 Context 配合使用,在某些场景下瓶颈非常明显(#20 #36
  • 生命周期不够完善,无法控制何时装载何时卸载(#12)
  • 强制将数据存储到全局,无法支持局部状态

为了解决上述问题,在此 RFC 中,尝试将底层实现改为基于 Context。不过基于 Context 虽然可以解决上述全部问题,但也会存在一些新的弊端:

  • API 较为复杂,特别是需要用户手动在组件树中添加 Provider

API

创建 model

import {createModel} from 'hox'

function useCounter() {
  // ...
}

export const CounterModel = createModel(useCounter)
// 或
export default createModel(useCounter)

提供 model

import {CounterModel} from './counter.model.ts'

function App() {
  return (
    <CounterModel.Provider>
      <div>
        {/* ... */}
      </div>
    </CounterModel.Provider>
  )
}

获取/订阅 model

import {useModel} from 'hox'
import {CounterModel} from './counter.model.ts'

function Foo() {
  const counterModel = useModel(CounterModel)
  return (
    ...
  )
}

只读(对应 v1 API 中的 useXxxModel.data

<CounterModel.Provider ref={yourModelRef}> // 通过 ref 的方式获取
</CounterModel.Provider>

传参

<CounterModel.Provider startFrom={123}> // 通过 ref 的方式获取
</CounterModel.Provider>
interface Props {
  startFrom: number
}
const CounterModel = createModel<Props>((props) => {
  const [count, setCount] = useState(props.startFrom)
  // ...
})

由于存在参数传递,需要给 createModel 增加一个 options.memo 参数来控制何时触发重渲染:

const CounterModel = createModel<Props>((props) => {
  const [count, setCount] = useState(props.startFrom)
  // ...
}, { // <- options
  memo: true // 开启 memo 后,Provider 的重渲染逻辑和普通 React 组件被 memo 后的逻辑类似
})

如果语法较为复杂的话,可以考虑把 memo 的默认值设置为 true,因为绝大部分场景下都是需要 memo 的。

其他

是叫 model 好还是叫 store 好?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:24 (14 by maintainers)

github_iconTop GitHub Comments

6reactions
brickspertcommented, Jul 14, 2020

看了下 unstated-next API,感觉我们就是多了一个 memo,其它的几乎一样。

我给个极简思路,我们只在 v1 基础上提供一个 Provider,如果用户使用了 Provider,我们就把 model 挂在这个 Provider 上。如果没有提供,则保持 v1 的逻辑。

4reactions
tivjoecommented, Jul 5, 2020

这样的改动违背了最初的设计理念,不叫modal了确实叫store了,称不上是下一代的状态管理库了,和其它context的库有什么区别呢?

Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC 6762: Multicast DNS
RFC 6762 Multicast DNS February 2013 Table of Contents 1. Introduction . ... A desktop computer with a screen might put up a...
Read more >
V2 Webhooks - Box Developer Documentation
An RFC-3339 timestamp that identifies when the payload was sent. BOX-SIGNATURE-PRIMARY, A signature created using the primary signature key configured for this ...
Read more >
Host Router Support for OSPFv2 (RFC8770)
RFC 8770 Host Router Support for OSPFv2 Abstract The Open Shortest Path First Version 2 (OSPFv2) protocol does not have a mechanism for...
Read more >
PKCE: What and Why? - Dropbox Tech Blog
“PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent several attacks and to be able to securely perform the...
Read more >
SOLA® ATR Specifications Guide for BOX Confidential
5.2.9 Add V, W values to Account Type (RFC BX05-0016) ... SOLA® ATR Specifications Guide for BOX, v2.1. Introduction.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found