@cainiaofe/cn-ui-m
Version:
91 lines (90 loc) • 2.96 kB
JavaScript
import * as React from 'react';
import isNil from 'lodash/isNil';
/**
* useValue 受控 & 非受控 value 逻辑封装
* @param props 组件的props
* @param defaultValue 默认value
* @param options
* @param options.valueName value 在 props 上的名称
* @param options.fitValue 将外界传入的 value 进行转化
* @param options.compare 用于对比两个 value 是否相同(返回 true 表示相同)
* @return [value, setValue, isControlled]
*/
export function useValue(props, defaultValue, options) {
var _a = options || {}, _b = _a.valueName, valueName = _b === void 0 ? 'value' : _b, fitValue = _a.fitValue, compare = _a.compare;
var defaultName = React.useMemo(function () {
var n = valueName.substr(0, 1).toUpperCase() + valueName.substr(1);
return "default".concat(n);
}, [valueName]);
var isControlled = valueName in props;
var defaultVal = React.useMemo(function () {
var v = defaultValue;
if (defaultName in props) {
v = props[defaultName];
}
if (isControlled) {
v = props[valueName];
}
if (isNil(v)) {
v = defaultValue;
}
if (fitValue) {
v = fitValue(v);
}
return v;
}, []);
var getControlledValue = function () {
var x = props[valueName];
if (isNil(x)) {
if (fitValue) {
return fitValue(defaultValue);
}
return defaultValue;
}
if (fitValue) {
return fitValue(x);
}
return x;
};
var _c = React.useState(defaultVal), value = _c[0], setValue = _c[1];
var propValue = React.useRef(defaultVal);
// 同步 prop 值
React.useEffect(function () {
if (isControlled) {
var newValue = getControlledValue();
var isSame = compare
? compare(newValue, propValue.current)
: newValue === propValue.current;
if (!isSame) {
propValue.current = newValue;
setValue(newValue);
}
}
}, [props[valueName], props.dataSource]);
// 同时修改 state 和 prop 值
var setPropValue = function (val) {
var isSame = compare
? compare(val, propValue.current)
: val === propValue.current;
if (!isSame) {
propValue.current = val;
setValue(val);
}
};
if (isControlled) {
// 受控模式
return [propValue.current, setValue, isControlled, setPropValue];
}
return [value, setValue, isControlled, setPropValue];
}
var counter = 0;
export function guid(prefix) {
if (prefix === void 0) { prefix = ''; }
counter += 1;
return "".concat(prefix).concat(counter);
}
export function useGuid(prefix) {
if (prefix === void 0) { prefix = ''; }
var id = React.useRef(guid(prefix));
return id.current;
}