erich
erich

Reputation: 261

PropTypes.instanceOf of functional component not working

I'm trying for set propTypes of children for a specific type, so when passing children of the wrong type, it throws a warning, but currently, even after saying that children: PropTypes.arrayOf(Option) it gets completely ignored and accepts other types too.

I want SortBy to accept only a list of Option, but it receives native html option without warnings.

Here is the sandbox: https://codesandbox.io/s/sleepy-currying-fwdlq

And here is the code:

sort-by.js

import React from 'react';
import PropTypes from 'prop-types';
import {Option} from './option';

const SortBy = ({children, onChange}) => (
  <select onChange={onChange}>
    <Option>---</Option>
    {children}
  </select>
);

SortBy.Option = Option;

export {
  SortBy,
};

SortBy.propTypes = {
  onChange: PropTypes.func.isRequired,
  children: PropTypes.arrayOf(Option).isRequired,
};

option.js

import React from 'react';
import PropTypes from 'prop-types';

export function Option({ children }) {
  return <option>{children}</option>;
}

Option.propTypes = {
  children: PropTypes.oneOf(['id', 'state', '---']).isRequired,
};

app.js

import React from 'react';
import {List, Issue, SortBy} from './components';


function App() {
  return (
    <div>
      <SortBy onChange={() => {}}>
        <SortBy.Option>
          id
        </SortBy.Option>
        <SortBy.Option>
          state
        </SortBy.Option>

        {/* this one should throw a warning saying that
        option is not an instance of Option, but it doesn't */}
        <option>---</option>
      </SortBy>
    <div/>
  );
}

export default App;

Upvotes: 2

Views: 3528

Answers (1)

erich
erich

Reputation: 261

What I was trying to accomplish is not actually feasible due to:

sophiebits commented on Aug 26, 2015

This would be called elementOfType if we do want it, though I'm not sure we do since if a component is expecting a <Button /> element you should (ideally) be able to pass <PurpleButton /> and have that work too.

https://github.com/facebook/react/pull/4716

But there is a workaround that look like this:

// Validates a singular field
var fieldType = React.PropTypes.shape({
    type: React.PropTypes.oneOf([Field])
})

// Accepts either a single field, or an array of fields
// Note: Reject a Form with no children
Form.propTypes = {
    children: React.PropTypes.oneOfType([
        React.PropTypes.arrayOf(fieldType), // array of fields
        fieldType // singular field
    ]).isRequired
}

https://github.com/facebook/react/issues/2979#issuecomment-222379916

Upvotes: 2

Related Questions