berkes
berkes

Reputation: 27553

How can I provide the PropTypes for a inner, nested component?

I have a component that is rather complex, so I build it from nested components. Simplified:

export function BlockProvideFeedback(props) {  
  const handleSelect = (event) => console.log(event);

  const Form = (props) => (
    <>
      <RadioList selected={props.selected} />
      <Button onClick={handleSelect} />
    </>
  );

  const Message = () => (
    <p>Thanks for the feedback</p>
  );

  if (props.feedbackStatus == 'agreed') {
    return(<Form selected='done'/>);
  if (props.feedbackStatus == 'pending') {
    return(<Form selected='needswork'/>);
  } else {
    return(<Message/>);
  }
};

BlockProvideFeedback.propTypes = {
  feedbackStatus: PropTypes.string.isRequired,
};

The linter is, rightfully IMO, pointing out that props.selected in Form(props) needs propTypes. But I don't know where and how to provide them. 'selected' is missing in props validation.

I tried the obvious:

BlockProvideFeedback().Form.propTypes { //... }

But that throws errors because I'm instantiating the component (by calling the function) without the proper context, props, providers etc.

How do I put selected for my nested component, in a props validation?

Or am I maybe doing something else horribly wrong: for example, my entire setup of nesting the maybe is so non-react-ish that tooling, like linters, will fail on it without being able to solve it?

Upvotes: 0

Views: 692

Answers (1)

secan
secan

Reputation: 2669

If Form and Message are not intended to be shared and reused, I would convert them in "render functions"; something like:

export function BlockProvideFeedback(props) {  
  const handleSelect = (event) => console.log(event);

  const renderForm = (selectedVal) => (
    <>
      <RadioList selected={selectedVal} />
      <Button onClick={handleSelect} />
    </>
  );

  const renderMessage = () => (
    <p>Thanks for the feedback</p>
  );

  if (props.feedbackStatus == 'agreed') {
    return renderForm('done');
  if (props.feedbackStatus == 'pending') {
    return renderForm('needswork');
  } else {
    return renderMessage();
  }
};

BlockProvideFeedback.propTypes = {
  feedbackStatus: PropTypes.string.isRequired,
};

Not really an answer to your question, I know, but it seems to me this case can be a sort of "XY problem".

Upvotes: 1

Related Questions