ReactJs: какими должны быть Проптипы для этого.реквизит.дети?
учитывая простой компонент, который отображает своих детей:
class ContainerComponent extends Component {
static propTypes = {
children: PropTypes.object.isRequired,
}
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
export default ContainerComponent;
вопрос: Какой должна propType детей упорка быть?
когда я устанавливаю его как объект, он терпит неудачу, когда я использую компонент с несколькими детьми:
<ContainerComponent>
<div>1</div>
<div>2</div>
</ContainerComponent>
предупреждение: неудачный тип опоры: недопустимый опора
children
типаarray
поставляется вContainerComponent
ожидаетсяobject
.
если я установлю его как массив, он потерпит неудачу, если я дам его только один ребенок, то есть:
<ContainerComponent>
<div>1</div>
</ContainerComponent>
Warning: Failed prop тип: недопустимый prop детей типа объекта поставляется в ContainerComponent, ожидаемый массив.
пожалуйста, посоветуйте, должен ли я просто не утруждать себя проверкой проптипов для детских элементов?
6 ответов
попробуйте что-то вроде этого, используя oneOfType
или PropTypes.node
import PropTypes from 'prop-types'
...
static propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).isRequired
}
или
static propTypes = {
children: PropTypes.node.isRequired,
}
для меня это зависит от компонента. Если вы знаете, что вам нужно, чтобы он был заполнен, вы должны попытаться указать исключительно или несколько типов, используя:
PropTypes.oneOfType
однако я в основном нахожу, с более общими компонентами, которые могут иметь много типов детей, я рад использовать:
PropTypes.any
если вы хотите обратиться к компоненту React, то вы будете искать
PropTypes.element
хотя
PropTypes.node
описывает все, что может быть rendered-строки, числа, элементы или массив этих вещей. Если тебе это подходит, то вот так.
ответы здесь, похоже, не совсем охватывают проверку детей точно. node
и object
слишком разрешительный, я хотел проверить точный элемент. Вот что я в итоге использовал:
- использовать
oneOfType([])
разрешить для одного или для проживания детей - использовать
shape
иarrayOf(shape({}))
для одиночных и массива детей, соответственно - использовать
oneOf
для самого дочернего элемента
в конце концов, что-то вроде это:
import PropTypes from 'prop-types'
import MyComponent from './MyComponent'
children: PropTypes.oneOfType([
PropTypes.shape({
type: PropTypes.oneOf([MyComponent]),
}),
PropTypes.arrayOf(
PropTypes.shape({
type: PropTypes.oneOf([MyComponent]),
})
),
]).isRequired
этот вопрос помог мне понять это более четко: https://github.com/facebook/react/issues/2979
Если вы хотите точно соответствовать типу компонента, проверьте это
MenuPrimary.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(MenuPrimaryItem),
PropTypes.objectOf(MenuPrimaryItem)
])
}
Если вы хотите точно соответствовать некоторым типам компонентов, проверьте это
const HeaderTypes = [
PropTypes.objectOf(MenuPrimary),
PropTypes.objectOf(UserInfo)
]
Header.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.oneOfType([...HeaderTypes])),
...HeaderTypes
])
}
документация PropTypes имеет следующие
// Anything that can be rendered: numbers, strings, elements or an array
// (or fragment) containing these types.
optionalNode: PropTypes.node,
Итак, вы можете использовать PropTypes.node
для проверки объектов или массивов объектов
static propTypes = {
children: PropTypes.node.isRequired,
}
попробуйте пользовательские propTypes:
const childrenPropTypeLogic = (props, propName, componentName) => {
const prop = props[propName];
return React.Children
.toArray(prop)
.find(child => child.type !== 'div') && new Error(`${componentName} only accepts "div" elements`);
};
static propTypes = {
children : childrenPropTypeLogic
}
const {Component, PropTypes} = React;
const childrenPropTypeLogic = (props, propName, componentName) => {
var error;
var prop = props[propName];
React.Children.forEach(prop, function (child) {
if (child.type !== 'div') {
error = new Error(
'`' + componentName + '` only accepts children of type `div`.'
);
}
});
return error;
};
class ContainerComponent extends Component {
static propTypes = {
children: childrenPropTypeLogic,
}
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
class App extends Component {
render(){
return (
<ContainerComponent>
<div>1</div>
<div>2</div>
</ContainerComponent>
)
}
}
ReactDOM.render(<App /> , document.querySelector('section'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<section />