循环/递归反应PropTypes

时间:2017-05-29 03:31:55

标签: reactjs recursion cycle react-proptypes

不要混淆a similar question询问如何递归地定义 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)} />
);

我可以立即想到的一个hacky解决方法是改为传递某种标识符,而不是该组件用来查找一些引用的prop。有没有其他方法,没有改变React的类型检查器来防止循环?

注意:对于那些感兴趣的人,除了日志警告以及潜在的一些轻微的性能影响之外,做我上面所说的事情也可以正常工作。

1 个答案:

答案 0 :(得分:3)

我提出的处理递归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
};