Hooks

怎么使用hooks,将service注入到react组件中:

简单用法

const app = () => {
  const [state, actions] = useService(DemoService)
  // state.count 
  // actions.add, actions.reset, actions.setCount ...
  return <div>{state.count}</div>
}
// 等价于:
const app2 = () => {
  // 手动使用container获取DemoService的实例,切忌不可直接new DemoService
  const demoService = container.resolveInScope(DemoService)
  const [state, actions] = useServiceInstance(demoService)
  // ...
}

使用Selector

上述例子中,当state变化的时候,组件也会重新渲染,但是有的时候,全部重新是一种浪费,因此这里也实现了一个类型于react-redux里面的mapStateToProps 的筛选函数:

const app =() => {
  // 只有当count变化的时候,
  const [count, actions] = useService(DemoService, state => state.count)
  // count 
  // actions.add, actions.reset, actions.setCount ...
  return <div>{count}</div>
}
// 等价于
const app2 = () => {
  // 手动使用container获取DemoService的实例,切忌不可直接new DemoService
  const demoService = container.resolveInScope(DemoService)
  const [count, actions] = useServiceInstance(demoService, state => state.count)
  // ...
}

特别的,当你完全不想让state的变化触发重渲染的时候可以这样:

const [,actions] = useService(DemoService, () => undefined)
// 等价于:
const actions = useService(DemoService)
// 等价于:
const [,actions] = useServiceInstance(demoService, () => undefined)
// 等价于:
const actions = useServiceInstance(demoService)

限定Scope

默认注入都是单例(Singleton),可以手动修改:

const app =() => {
  const [count] = useService(DemoService, state => state.count,{scope: Transient})
  const [state, actions] = useService(DemoService, {scope: Transient})
  useEffect(() => actions.add(1), [])
  // count 
  // actions.add, actions.reset, actions.setCount ...
  return <div> count1: {count}, count2: {state.count} </div>
  // count1: 0, count2: 1
}

scope预定义的值有:SingletonTransient, Request, 也可以使用自定义的scope,自定义scope都是单例的,相同scope获取的实例是一样的,不同scope获取的实例不同,Demo(https://codesandbox.io/s/service-x-scope-8oool

Transient注入的实例是跟随组件生命周期的,当组件unmount的时候,注入实例也会被销毁。

当scope为单例情况(非Transient or Request),options中可以设置resetOnUnmount参数,代表当前store中的state会随着组件的unmount进行重置,并且在组件unmount到mount这段时间里,store会处于休眠状态,不响应任何外部调用或者Observable事件。

实例如何获取:useService返回数组的第三项:

const [state, actions, service] = useService(DemoService, {scope: Transient})

然后就可以把这个service传递给子组件,子组件useServiceInstance就能注入同一个service实例了。

Last updated

Was this helpful?