В моей кодовой базе есть компонент высшего порядка (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 для использования для проверки. Эти индексы хранилища получены из информации в массиве объектов, описывающих входы. Наличие доступа к этому потенциально динамическому массиву является причиной, по которой я хочу иметь возможность вызывать свой HOC в жизненном цикле React.
Таким образом, сопоставление моего массива входных данных может выглядеть примерно так...
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, он будет работать нормально. - person Felix Kling   schedule 05.01.2017