Cyclical/Recursive React PropTypes

Cyclical/Recursive React PropTypes

不要与 询问如何递归地 定义 PropTypes 混淆,我正在寻找一种方法来传递 的参数本身 是递归的,没有:

这是一个简单的示例,说明如何使用它。

const fields = [{
        accessor: 'firstName',
        type: 'text',
        required: true,
        label: 'First Name',
        placeholder: 'Enter your first name'
}];

fields.push({
    accessor: 'children',
    type: 'dynamicList',
    label: 'Children',
    fields: fields
});

return (
    <Form 
        fields={fields} 
        onSave={data => console.log(data)} />
);

我立即想到的一个变通方法是传递某种标识符,而不是组件用来查找某些引用的道具。有没有另一种方法,不改变 React 的类型检查器来防止循环?

注意:对于那些感兴趣的人,据我所知,执行上述操作效果很好,除了日志警告和潜在的一些轻微性能影响。

我想出的一种处理递归 PropTypes 的 prop 循环的方法是对惰性求值方法的调整,如下所示:

function lazyFunction(f, _lazyCheckerHasSeen) {
    return function() {
        if (_lazyCheckerHasSeen.indexOf(arguments[0]) != -1) {
            return true;
        }

        _lazyCheckerHasSeen.push(arguments[0]);
        return f().apply(this, arguments);
    }
}

像这样使用,对于上述示例:

const lazyFieldType = lazyFunction(function () { 
    return fieldType;
}, []);

const fieldType = PropTypes.shape({
    accessor: PropTypes.string.isRequired,
    type: PropTypes.oneOf(['text', 'multitext', 'checkbox', 'select', 'multiselect', 'section', 'dynamicList']).isRequired,
    required: PropTypes.boolean,
    label: PropTypes.string,
    placeholder: PropTypes.string,
    fields: PropTypes.arrayOf(lazyFieldType),
});

Form.propTypes = {
    fields: PropTypes.arrayOf(fieldType),
    onSave: PropTypes.func.isRequired
};