English | 简体中文
npm install hooxjs -S
// 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
}
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
,初始化全局状态。
import createHoox from 'hooxjs'
const state = { count: 0 }
export const {
Provider,
getHoox,
useHoox,
setHoox,
resetHoox,
createContainer
} = createHoox(state)
由于 hoox 基于context
实现,故而消费全局状态的组件需要包裹在相应Provider
下。
Provider
还提供了一个 Prop,initialState
。它可选地接收一个对象,它会与createHoox
时传递的初始状态合并,成为 hoox 的最终全局状态初始值。
function App() {
return <Provider initialState={{ count: 1 }}>
<YourFunctionComponent>
</Provider>
}
这是一个Provider
的语法糖。
createContainer
的第一个参数是需要消费全局状态的函数式组件(只要根组件即可),第二个参数即同Provider
的initialState
,会与创建 Store
时的状态合并成初始全局状态。
const App = createContainer(YourFunctionComponent, { count: 2 })
本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
常用于创建一个全局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
的行为跟类组件中的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
的行为跟函数式组件中,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 })
}
将全局状态注入到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)