react service is a react state manager
npm install ajanuw-react-rxserviceUse dependency injection to create services, inspired by Angular
sh
$ npm i ajanuw-react-rxservice
$ npm i rxjs
`如果你想使用
constructor依赖注入`sh
$ npm i reflect-metadata
`配置
tsconfig.json`json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
},
}
`全局服务
$3
`ts
@Injectable()
class AppService {
i = 0;
}
`@Injectable 立即注册一个全局服务,当数据变化时通知订阅者$3
`tsx
export default memo(() => {
const [as] = useService(AppService); return (
builder={() => {
return (
{as.i}
);
}}
/>
);
});
`RxService 组件会自动订阅全局服务,收到响应时触发更新
局部服务(非全局服务)
$3
`ts
@Injectable({ global: false })
class PS implements ServiceProxy {
i = 0;
OnCreate() {}
OnUpdate() {}
OnDestroy() {}
}
`使用
Injectable时可以传入一些配置项,将global设置为false注册为局部服务,并且不会立即注册提供了一些钩子函数,用于监听局部服务的生命周期
$3
`tsx
export default memo(() => {
const [ps] = useService(PS); return (
services={[PS]}
global={false}
builder={() => {
return (
{ps.i}
);
}}
/>
);
});
`使用
useService时初始化局部服务RxService的services属性用于添加局部服务,global设置为fasle将不会订阅全局服务,如果你需要局部服务并且也需要全局服务可以无视此选项RxService 被销毁时,services中的所有局部服务也会自动销毁,销毁前会调用 OnDestroyOnCreate 在组件渲染完成之前触发其他问题
$3
1. 使用
@Ignore装饰器
`ts
@Injectable({ global: false })
class PS implements ServiceProxy { @Ignore()
ref_ = React.createRef();
}
` 2. 使用
autoIgnore配置选项,会自动无视以_结尾的属性
`ts
@Injectable({ global: false, autoIgnore: true })
class PS implements ServiceProxy {
ref_ = React.createRef();
}
`$3
1. 使用
constructor依赖注入
`ts
import "reflect-metadata"; @Injectable()
class UserinfoService {}
@Injectable()
class AppService {
constructor(public readonly userinfo: UserinfoService) {}
}
` 2. 使用静态属性
`ts
@Injectable()
class UserinfoService {
static ins: UserinfoService;
} @Injectable()
class AppService {
userinfo = UserinfoService.ins;
i = 0;
}
` 3. 使用
@Late装饰器
`ts
@Injectable({ id: "UserinfoService" })
class UserinfoService {
i = 0;
} @Injectable()
class AppService {
@Late("UserinfoService")
userinfo!: UserinfoService;
@Late("AfterService")
after!: any;
}
@Injectable({ id: "AfterService" })
class AfterService {}
`
@Late装饰器需要提供一个服务的唯一id,如果这个服务已经被初始化则会立即初始化属性(userinfo),否则会一直等到服务初始化时才设置属性(after) 4. 在组件中使用多个服务?
`ts
@Injectable()
class UserinfoService {} @Injectable()
class AppService {}
@Injectable({ global: false })
class PS {}
export default memo(() => {
const [ps, as, us] = useService(PS, AppService, UserinfoService);
return (
services={[PS]}
builder={() => {
return
;
}}
/>
);
});
`$3
只能在局部服务中在这样做!
`ts
@Injectable({ global: false })
class PS implements ServiceProxy {
i = 0;
OnDestroy() {
return true;
}
}
` 如果在页面销毁时
i=10,并且在OnDestroy钩子中返回true,那么下次重启这个服务时,数据不会被初始化而是继续使用上一次的数据,再次进入页面你会直接看到i=10而不是i=0 服务从第一次创建就一直存在于内存中,销毁只是一个状态,在销毁状态下所有的变更都不会通知订阅者
当再次启动销毁状态的服务时,只是取消了销毁状态,数据的初始化取决于上一次
OnDestroy钩子的返回值,如果返回true将继续使用以前的数据,否则会重新初始化一个实例,并创建一个新的代理然后触发OnCreate钩子$3
`ts
@Injectable()
class PS {
i = 0; add() {
noreact(() => {
this.i++
})
}
}
` 在
noreact的钩子函数中,改变数据时不会通知订阅者
作为装饰器使用也可以达到同样的效果
`ts
@Injectable()
class PS {
i = 0; @noreact()
add() {
this.i++
}
}
`$3
1.
Watch 装饰器,监听一个或多个属性的变更
`ts
class PS {
i = 0;
obj = { i: 0 } @Watch(['this.i', 'this.obj.i'])
watch(newVal: number, oldVal: number, key: string) {
console.log(key, newVal, oldVal);
}
}
`2.
AutoWatch 自动监听属性变化`ts
class PS implements ServiceProxy {
i = 0;
j = 0; @AutoWatch()
watch() {
this.j = this.i * 2
}
}
`$3
-
Array
- [object Object]
- [object Set]
- [object Map]
- [object WeakMap]
Run test
`sh
$ npm start
$ npm t
``