【发布时间】:2017-05-19 07:46:48
【问题描述】:
在我的代码库中,我有一个高阶组件 (HOC),用于将所有输入验证功能添加到给定组件。在像这样定义的组件上使用时效果很好......
let NameInput = React.createClass({
render() {
return (
<div>
<label htmlFor="name-input">Name</label>
<input name="name-input" />
</div>
);
}
});
let NameInput = addInputValidation(NameInput);
module.exports = NameInput;
但我现在需要根据来自服务器的数组定义一系列输入。像这样的...
let TestApp = React.createClass({
render() {
// Pretend the names array came from the server and is actually an array of objects.
let names = ['First name', 'Middle name', 'Last name'];
// Map over our names array in hopes of ending up with an array of input elements
let nameComponents = names.map((name, index) => {
let componentToRender = (
<div key={index}>
<label htmlFor={name}>{name}</label>
<input name={name} />
</div>
);
// Here is where I'd like to be able to use an HOC to wrap my name inputs with validation functions and stuff
componentToRender = addInputValidation(componentToRender);
return componentToRender;
})
return (
<div>
<p>Enter some names:</p>
{nameComponents}
</div>
);
}
})
let addInputValidation = function(Component) {
let hoc = React.createClass({
getInitialState() {
return {
isValid: false
};
},
render() {
return (
<div>
<Component {...this.props} />
{this.state.isValid ? null : <p style={{color: "red"}}>Error!!!!</p>}
</div>
);
}
});
return hoc;
}
module.exports = TestApp;
React 不喜欢你尝试渲染从另一个组件中调用 HOC 的结果。
我认为这与我的 componentToRender 不是真正的 React 组件或其他东西有关。
所以我的问题是......
为什么我不能从另一个组件中调用 HOC?
有没有办法在数组的每个元素上调用 HOC?
这是一个可能有帮助的 jsfiddle:https://jsfiddle.net/zt50r0wu/
编辑以澄清一些事情:
我映射的数组实际上是一个描述输入细节的对象数组。包括输入的类型(选择、复选框、文本等)。
另外,我的addInputValidation HOC 实际上接受的参数不仅仅是组件。它需要一组存储索引,这些索引将从 Redux 存储中提取以用于验证。这些存储索引源自描述输入的对象数组中的信息。访问这个潜在的动态数组是我希望能够在 React 生命周期内调用我的 HOC 的原因。
所以映射到我的输入数组可能看起来更像这样......
let Select = require('components/presentational-form/select');
let Text = require('components/presentational-form/select');
let CheckboxGroup = require('components/presentational-form/select');
let TestApp = React.createClass({
render() {
// Pretend the inputs array came from the server
let inputs = [{...}, {...}, {...}];
// Map over our inputs array in hopes of ending up with an array of input objects
let inputComponents = inputs.map((input, index) => {
let componentToRender = '';
if (input.type === 'select') {
componentToRender = <Select labelText={input.label} options={input.options} />;
} else if (input.type === 'text') {
componentToRender = <Text labelText={input.label} />;
} else if (input.type === 'checkbox') {
componentToRender = <CheckboxGroup labelText={input.label} options={input.options} />;
}
// Here is where I'd like to be able to use an HOC to wrap my name inputs with validation functions and stuff
componentToRender = addInputValidation(componentToRender, input.validationIndexes);
return componentToRender;
})
return (
<div>
<p>Enter some names:</p>
{inputComponents}
</div>
);
}
})
【问题讨论】:
-
addInputValidation期望传递一个组件,但您传递的是一个 元素 (<div />)。那是行不通的。 “有没有办法在数组的每个元素上调用 HOC?” 当然。 HOC 是一个函数,很容易为数组的每个元素调用一个函数。这是否有效取决于元素是什么以及函数期望什么。如果你有一个 components 数组,它会正常工作。 -
@Kory 你能告诉我们你的 addInputValidation HOC 吗?
标签: javascript reactjs higher-order-functions higher-order-components