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)