Thanks to visit codestin.com
Credit goes to github.com

Skip to content

hox v2 RFC #37

@awmleer

Description

@awmleer

背景

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

为了解决上述问题,在此 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 好?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions