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>
предупреждение: не удалось тип опоры: недопустимый опора детей типа объекта поставляется в 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
описывает все, что может быть визуализация-строки, числа, элементы или массив этих вещей. Если это подходит вам, то это путь.
ответы здесь, кажется, не совсем точно проверяя детей.
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, }
попробуйте пользовательские проптипы:
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 />