一个让在 React 中使用 Caslin 更加简单的工具库
English | 中文
npm install @caslin/feature @caslin/react --save
假定已经存在一个 feature.js
文件,它暴露了利用 FeatureBuilder.define() 生成的 feature 对象。
组件的属性名与 @caslin/feature 中的相同,当特性检验结果为 true 时,将根据 <Can>
组件的 children 视情况进行渲染,你还能够传递一个 fallback
render prop 来作为后备渲染元素。
import { Can } from '@caslin/react';
import feature from './feature';
// 'chidlren' as render function
<Can env="featEnv1" action="create" subject="Article" feature={feature}>
{() => <button onClick={this.createArticle.bind(this)}>Create Article</button>}
</Can>
// not
<Can not env="featEnv1" action="create" subject="Article" feature={feature}>
{() => <button onClick={this.createArticle.bind(this)}>Create Article</button>}
</Can>
// passThrough, pass match result as parameter
<Can passThrough env="featEnv1" action="create" subject="Article" feature={feature}>
{(match) => <button disabled={match} onClick={this.createArticle.bind(this)}>Create Article</button>}
</Can>
// 'children' element
<Can env="featEnv1" action="create" subject="Article" feature={feature}>
<button onClick={this.createArticle.bind(this)}>Create Article</button>
</Can>
// fallback property will be rendered if feature checking result is false
<Can env="featEnv1" action="create" subject="Article" feature={feature} fallback={<div>You don't have permissioin to create Article.</div>}>
<button>Create Article</button>
</Can>
一般使用这个组件的时候已经调用过 feature.setEnv() 设置好了当前的默认环境,同样地你还能够传递一个 fallback
render prop 来作为后备渲染元素。
import { Env } from '@caslin/react';
import feature from './feature';
<Env is="featEnv1" feature={feature}>
{() => <div>feature env 1</div>}
</Env>
<Env not="featEnv1" feature={feature}>
{() => <div>feature env 2</div>}
</Env>
<Env in={['featEnv1', 'featEnv2']} feature={feature}>
{() => <div>feature env 1</div>}
</Env>
<Env notIn={['featEnv2', 'featEnv3']} feature={feature}>
{() => <div>feature env 1</div>}
</Env>
// passThrough, pass match result as parameter
<Env passThrough is="featEnv1" feature={feature}>
{(match) => <div>{match ? 'is' : 'not'} env 1</div>}
</Env>
// fallback property will be rendered if feature checking result is false
<Env is="featEnv1" feature={feature} fallback={<div>Current env is not featureEnv1.</div>}>
{() => <div>feature env 1</div>}
</Env>
传递 feature
作为 createCheckerBoundTo()
的参数得到高阶组件。
// featChecker.js
import { createCheckerBoundTo } from '@caslin/react';
import feature from './feature';
export default createCheckerBoundTo(feature); // { Can, Env }
之后就可以直接使用预定义好了 feature
的 <Can>
和 <Env>
,而不用再次传递了:
import featUtil from './featChecker';
const { Can, Env } = featUtil;
<Can action="create" subject="Article">
{() => <button onClick={this.createArticle.bind(this)}>Create Article</button>}
</Can>
<Env is="featEnv1">
{() => <div>feature env 1</div>}
</Env>
传递 Context.Consumer
作为 createContextualChecker()
的参数得到高阶组件。
// featChecker.js
import React from 'react';
import { createContextualChecker } from '@caslin/react';
import feature from './feature';
export const FeatContext = React.createContext(feature);
export default createContextualChecker(FeatContext.Consumer); // { Can, Env }
// High hierarchy component
import feature from './feature';
import { FeatContext } from './featChecker';
...
<FeatContext.Provider value={feature}>
{// ...chidlren}
</FeatContext.Provider>
...
// Use HOC
import featUtil from './featChecker';
const { Can, Env } = featUtil;
<Can action="create" subject="Article">
{() => <button onClick={this.createArticle.bind(this)}>Create Article</button>}
</Can>
<Env is="featEnv1">
{() => <div>feature env 1</div>}
</Env>