前端业务代码配置化

如何写好业务代码?
在前端工做中有不少业务性代码,若是书写不规范,那么对后期的维护将是很是致命的。html

判断配置化

业务场景

后端数据库中常常会一个字段具有几个不一样的状态,好比:前端

status: 2
// 各个字段对应的含义
0: 出生
1: 儿童
2: 少年
3: 中年
4: 老年
  • 这样不一样的数字表明的含义,须要在前端展现。
  • 须要根据不一样的状态,前端去作不一样的处理

方法一(switch)(bad)

下面这段代码就是常见的无限if/else或者switch场景react

// 业务代码
switch (status) {
    case 0: 
        // do something
        return '出生';
    case 1:
        // do something
        return '儿童';
    ... ...
    default:
        return '';
}

这样作是很差的,由于若是后端再加了一个字段,好比git

5: 已死亡

那么前端须要从新修改switch函数,这样须要去修改对应的业务函数,无疑破坏了业务代码的完整性。github

方法二(写成配置文件)(better)

// cfg.js
export const cfg = new Map([
    [0, 出生],
    [1, 儿童],
    [2, 少年],
    ... ... 
]);

// 业务代码
cfg.get(status)

可是这样仅仅是显示相关的状态,若是涉及到状态的判断,那这样的处理方式就有些问题了,好比须要根据具体的状态去作对应的判断数据库

switch (status) {
    case 0:
        // do something
        return ;
    ... ...

}

像上面的状况,又变成了第一种状况,显然这种配置化的方式并不能知足。若是将对应的操做,与配置分割,则代码更加不易维护。后端

方法三(升级配置文件,处理代码集中)(better)

将状态处理集中起来,若是能将状态展现和对应的状态封装起来,那么就会让后期代码维护显得十分集中。app

// cfg.js
const status = new Map([
    [0, 出生],
    [1, 儿童],
    [2, 少年],
    ... ... 
]);
const checkIsBirth = (status, callback) => {
    if(status === 0) {
        callback && callback()
    }
}
export default {
    status,
    checkIsBirth
}
// 在具体使用中
import Person from './cfg.js'
const a = 1;
Person.status.get(a);
Person.checkIsBirth(a, () => {
    console.log('Person is in Birth state');
})

这样处理,若是之后status发生变化,只须要修改checkIsBirth中的判断逻辑就能够,只须要改动一处。函数

代码配置化

在使用react编写代码的过程当中,常常用到这样的状况,根据状况判断是否展现对应的组件。性能

方法一(流水线工做)(bad)

function Business({status, bug}) {
    return (
        <Fragment>
            {
                status === 0
                    ? (
                        <div>123</div>
                    )
                    : null
            }
            {
                bug === 1
                    ? (
                        <div>456</div>
                    )
                    : null
            }
        </Fragment>
    );
}

这样的写法若是仅仅只有一个其实还好,若是有不少个,在代码中会形成代码很是冗长,使假想一个页面中若是有不少这样的,代码看起来很是ugly。因此建议将代码分割开来,造成一个个小的组件,将对应的代码封装起来,将会使代码可读性提升一些。

方法二(组件粒度细化)(better)

function Business() {
    return (
        <Fragment>
            <One isShow={status === 0} />
            <One isShow={bug === 1} />
        </Fragment>
    );
}

// One
function One({isShow}) {
    return (
        <Fragment>
            {
                isShow === true
                ? (
                    <div>123</div>
                )
                : null
            }
        </Fragment>
    );
}

// Two
function Two({isShow}) {
    return (
        <Fragment>
            {
                isShow === true
                ? (
                    <div>456</div>
                )
                : null
            }
        </Fragment>
    );
}

若是常常这么写是否是会以为很烦,能够将通用的逻辑抽象为通用的组件。

方法三(高阶组件)(better)

其实能够观望一下decorator之后的用法,暂时没有找到使用的切入点。

function IsShowCom(isShow, Wrapped) {
    if (isShow === true) {
        return (Wrapped) => <Wrapped />
    }
    return () => null;
}
// 若是你想转发ref,你得这么作
function IsShowCom(isShow, Wrapped) {
    if (isShow === true) {
        return React.forwardRef((props, ref) => {
            return <Wrapped {...props} ref={ref} /> 
        });
    }
    return () => null;
}
// 
import IsShowCom from './isShowCom';

function Business() {
    const One = IsShowCom(
        status === 0,
        <div>
            123
        </div>
    );
    const Two = IsShowCom(
        bug === 1,
        <div>
            456
        </div>
    );
    return (
        <Fragment>
            <One/>
            <Two/>
        </Fragment>
    );
}

注意⚠️

不要在render中使用高阶组件,由于高阶组件每次返回来的都是新的组件,会使子组件的状态丢失 。可是在无状态组件中,这样使用并无什么问题,由于无状态组件自己就是随参数的变化而变化的,只是可能会产生性能问题。

总结

前端配置化的总体思路:

  • 针对不一样值进行不一样处理的时候,思考一下,是否是能够将判断逻辑代码集中起来
  • 针对组件的显示/隐藏,能够将具体的隐藏逻辑封装为高阶组件,便于维护
相关文章
相关标签/搜索