Skip to content

Latest commit

 

History

History
284 lines (212 loc) · 6 KB

README-cn.md

File metadata and controls

284 lines (212 loc) · 6 KB

Hoox

English | 简体中文

build test coverage downloads npm version

使用

安装

npm install hooxjs -S

创建一个 Store

// counterStore.js
import createHoox from 'hooxjs'

const state = {
  count: 1
}

export const { getHoox, useHoox, createContainer } = createHoox(state)

// 创建一个action
export const up = () => {
  const [hooxState, setHoox] = getHoox()
  return setHoox({
    count: hooxState.count + 1
  })
}

// 创建一个computed数据
export const useDoubleCount = () => {
  const [hooxState] = useHoox()
  return hooxState.count * 2
}

使用 Store

import React from 'react'
import ReactDom from 'react-dom'
import { useHoox, useDoubleCount, up } from './counterStore'

function Child() {
  const doubleCount = useDoubleCount()
  return <div>{doubleCount}</div>
}

function Counter() {
  const [hooxState] = useHoox()
  return (
    <div>
      <div>{hooxState.count}</div>
      <div onClick={() => up()} />
      <Child />
    </div>
  )
}

const Container = createContainer(Counter)

ReactDom.render(<Container />, document.getElementById('#root'))

API

createHoox

通过本api,初始化全局状态。

import createHoox from 'hooxjs'

const state = { count: 0 }

export const {
  Provider,
  getHoox,
  useHoox,
  setHoox,
  resetHoox,
  createContainer
} = createHoox(state)

Provider

由于 hoox 基于context实现,故而消费全局状态的组件需要包裹在相应Provider下。

Provider还提供了一个 Prop,initialState。它可选地接收一个对象,它会与createHoox时传递的初始状态合并,成为 hoox 的最终全局状态初始值。

function App() {
  return <Provider initialState={{ count: 1 }}>
    <YourFunctionComponent>
  </Provider>
}

createContainer

这是一个Provider的语法糖。

createContainer的第一个参数是需要消费全局状态的函数式组件(只要根组件即可),第二个参数即同ProviderinitialState,会与创建 Store时的状态合并成初始全局状态。

const App = createContainer(YourFunctionComponent, { count: 2 })

useHoox

api主要用于函数式组件内直接消费/更新全局状态;或用于构建自定义全局 Hook。

消费状态

function Counter() {
  const [hooxState] = useHoox()
  return (
    <div>
      <div>{hooxState.count}</div>
      <div onClick={() => up()} />
      <Child />
    </div>
  )
}

构建自定义全局 Hook

export const useDoubleCount = () => {
  const [hooxState, setHoox, resetHoox] = useHoox()
  const { count } = hooxState
  return [count * 2, () => setHoox({ count: count * 2 })]
}

getHoox

getHoox常用于创建一个全局action/effect。切忌,getHoox获取的全局状态不具有响应式。因此,如无特殊需要,不应该在函数式组件内直接引用。

创建一个 action

export const up = () => {
  const [hooxState, setHoox, resetHoox] = getHoox()
  return setHoox({
    count: hooxState.count + 1
  })
}

如下使用,当全局状态变更时,Counter并不会重新渲染

function Counter() {
  const [hooxState] = getHoox()
  return (
    <div>
      <div>{hooxState.count}</div>
      <div onClick={() => up()} />
      <Child />
    </div>
  )
}

setHoox

setHoox的行为跟类组件中的setState表现一致,会合并状态,但是没有回调。

setHoox可以直接从createHoox(state)的返回值中获取。

const { setHoox } = createHoox({ count: 0 })
export const updateCount = newCount => {
  return setHoox({
    count: newCount
  })
}

setHoox 也可以直接从getHoox()useHoox()的返回值中获取。

export const updateWithRecordOld = newCount => {
  const [oldState, setHoox] = getHoox()
  return setHoox({
    count: newCount,
    oldCount: oldState.count
  })
}

setHoox也支持传递一个函数,函数第一个入参为当前全局状态。

export const up = () => {
  const [, setHoox] = getHoox()
  return setHoox(oldState => ({
    count: oldState.count + 1
  }))
}

resetHoox

resetHoox的行为跟函数式组件中,useState返回的setState表现一致,它会重置全局状态。

setHoox可以直接从createHoox(state)的返回值中获取。

const { resetHoox } = createHoox({ count: 0 })
export const reset = () => {
  return resetHoox({ newCount: 0 })
}

resetHoox 也可以直接从getHoox()useHoox()的返回值中获取。

export const reset = () => {
  const [, , resetHoox] = getHoox()
  return resetHoox({ newCount: 0 })
}

connect

将全局状态注入到React组件的props之中。

函数式组件

const { connect } = createHoox({ count: 0 })

const Counter = ({ count }) => {
  return <div>{count}</div>
}

export default connect(state => ({ count: state.count }))(Counter)

类组件

// jsx
import React from 'react'

const { connect } = createHoox({ count: 0 })

@connect(state => ({ count: state.count }))
export default class Counter extends React.PureComponent {
  render() {
    return <div>{this.props.count}</div>
  }
}

PS: 由于装饰器不能修改被装饰对象的返回类型,connect的装饰器语法目前暂不支持TypeScript

// tsx
import React from 'react'

const { connect } = createHoox({ count: 0 })

class Counter extends React.PureComponent<{ count: number }> {
  render() {
    return <div>{this.props.count}</div>
  }
}

export default connect(state => ({ count: state.count }))(Counter)