Я пытаюсь указать конкретный класс компонента с типом Input, но это дает мне предупреждение.
Warning: Failed prop type: Invalid prop
childrensupplied toMyComponent.
MyComponent.js
import React, { Component, cloneElement } from 'react';
import Input from '../Input';
class MyComponent extends Component {
static propTypes = {
children: PropTypes.oneOfType([
PropTypes.shape({
type: PropTypes.oneOf([Input]),
}),
PropTypes.arrayOf(
PropTypes.shape({
type: PropTypes.oneOf([Input]),
})
),
]).isRequired,
}
renderChildren(child) {
const clone = cloneElement(child, {newProp: 'blaaa'});
return <div className='inner'>{clone}</div>;
}
render() {
const { children } = this.props;
return (
<div>
{React.Children.map(children, this.renderChildren)}
</div>
);
}
}
export default MyComponent;
Мой входной компонент урезан.
import React, { Fragment } from 'react';
const Input = ({name}) => (
<Fragment>
<input
/>
</Fragment>
);
export default Input;
Консольный журнал для детей:
$$typeof: Symbol(react.element)
key: null
props: {id: "email", placeholder: "email", type: "tel", name: "Email", styles: Array(1), …}
ref: null
type: ƒ Input(_ref)
_owner: FiberNode {tag: 1, key: "inputname", type: ƒ, stateNode: null, return: FiberNode, …}
_self: null
__proto__: Object
Просто добавил журнал консоли в мой отредактированный пост выше внизу поста.





Это предполагает, что ваш MyComponent будет последовательно получать один или несколько React Input.
Рабочий пример: https://codesandbox.io/s/045kw2pq30
компонент / NonInput.js
import React, { Fragment } from "react";
import PropTypes from "prop-types";
const NonInput = props => (
<code>
<pre>{JSON.stringify(props, null, 4)}</pre>
</code>
);
NonInput.propTypes = {
props: PropTypes.objectOf(PropTypes.string)
};
export default NonInput;
компоненты / Input.js
import React, { Fragment } from "react";
import PropTypes from "prop-types";
const Input = ({ newProp, ...props }) => (
<Fragment>
{console.info(newProp)}
<input className = "uk-input" {...props} />
</Fragment>
);
Input.propTypes = {
newProp: PropTypes.string,
props: PropTypes.objectOf(PropTypes.string)
};
export default Input;
компоненты / MyComponent.js
import React, { PureComponent, cloneElement } from "react";
import PropTypes from "prop-types";
import Input from "./Input";
const shapeOfChildren = PropTypes.shape({
type: PropTypes.oneOf([Input]).isRequired,
props: PropTypes.shape({
name: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
placeholder: PropTypes.string.isRequired
}).isRequired
});
class MyComponent extends PureComponent {
renderChildren = child => (
<div className = "inner">{cloneElement(child, { newProp: "blaaa" })}</div>
);
render = () => (
<div className = "uk-form-large">
{React.Children.map(this.props.children, this.renderChildren)}
</div>
);
}
MyComponent.propTypes = {
children: PropTypes.oneOfType([
shapeOfChildren,
PropTypes.arrayOf(shapeOfChildren)
]).isRequired
};
export default MyComponent;
компоненты / Example.js (удалите NonInput, сохраните, затем обновите страницу, чтобы удалить предупреждение PropType - если вы хотите, чтобы оно отображало более определенное предупреждение, напишите настраиваемая функция валидатора (пример внизу))
import React from "react";
import MyComponent from "./MyComponent";
import Input from "./Input";
import NonInput from "./NonInput";
export default () => (
<MyComponent>
<Input name = "firstName" type = "text" placeholder = "First Name" />
<Input name = "lastName" type = "text" placeholder = "Last Name" />
<NonInput name = "lastName" type = "text" placeholder = "Last Name" />
</MyComponent>
);
Спасибо, Мэтт, но узел подразумевает, что все может быть отрисовано как дочерний элемент: числа, строки, элементы или массив (или фрагмент). Я не хочу, чтобы что-то рендерилось. Я специально хочу, чтобы компонент Input был дочерним для рендеринга.
В этом случае замените node на Input от shape.
Но это то, что у меня есть в моем примере, и я получаю предупреждение? Можете ли вы привести пример формы ввода, которая отличается от моей?
PropTypes.shape ({тип: PropTypes.oneOf ([Вход]),})
Я сейчас не сижу за своим компьютером, но в основном вы должны скопировать структуру того, что вы предоставили выше, в console.info(this.props.children).
Правильно, и в моем посте это есть. тип: ƒ Вход (_ref)
тип: PropTypes.oneOf ([Вход]),
Обновленный ответ.
Кстати, вы можете пропустить эту лишнюю проверку. Поскольку вы ожидаете, что он всегда будет компонентом Input, нет необходимости передавать его как дочерний. Вместо этого просто передайте props в MyComponent и добавьте / клонируйте их в Input. В этом было бы больше смысла, и с ним было бы легче проверить.
Спасибо за полный пример.
Можете ли вы предоставить
console.info(this.props.children)во всех его вариантах / вариантах использования.