Ответ 1
РЕДАКТИРОВАНИЕ: Добавлен пример React FancyButton для codesandbox, а также пользовательская функция проверки проп, которая работает с новым API React.forwardRef
в React 16.3. API React.forwardRef
возвращает объект с функцией render
. Я использую следующую специальную проверку для подтверждения этого типа. - Спасибо за Ивана Самовара за то, что он заметил эту необходимость.
FancyButton: function (props, propName, componentName) {
if(!props[propName] || typeof(props[propName].render) != 'function') {
return new Error('${propName}.render must be a function!');
}
}
Вы хотите использовать , На самом деле... PropTypes.element
PropType.func
работает как для функциональных компонентов без сохранения состояния, так и для компонентов класса.
Я сделал песочницу, чтобы доказать, что это работает... Я подумал, что это нужно, учитывая, что сначала я дал вам ошибочную информацию. Очень сожалею об этом!
Вот код для теста на случай, если ссылка не работает:
import React from 'react';
import { render } from 'react-dom';
import PropTypes from "prop-types";
class ClassComponent extends React.Component {
render() {
return <p>I'm a class component</p>
}
}
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
const FSComponent = () => (
<p>I'm a functional stateless component</p>
);
const Test = ({ ClassComponent, FSComponent, FancyButton }) => (
<div>
<ClassComponent />
<FSComponent />
<FancyButton />
</div>
);
Test.propTypes = {
ClassComponent: PropTypes.func.isRequired,
FSComponent: PropTypes.func.isRequired,
FancyButton: function (props, propName, componentName) {
if(!props[propName] || typeof(props[propName].render) != 'function') {
return new Error('${propName}.render must be a function!');
}
},
}
render(<Test
ClassComponent={ ClassComponent }
FSComponent={ FSComponent }
FancyButton={ FancyButton } />, document.getElementById('root'));