React Prop Types Different Required Props Depending on Flag

Patrick Hund

I have a React component that gets a configuration object as a prop, it looks something like this:

{
    active: true,
    foo: {
         bar: 'baz'
    }
}

In some cases, I want to disable the feature that the component displays by passing in a different object with active: false, like this:

{
    active: false
}

This works fine and is not the problem.

However, I also want to make sure that client code that uses my component supplies the proper configuration object:

  • if active is true, foo is required
  • if active is false, foo is optional and does not need to be provided

How do I define prop types for a case like this?

I've tried:

MyComponent.propTypes = {
    config: PropTypes.oneOf([
        {
            active: false
        },
        PropTypes.shape({
            active: true,
            foo: PropTypes.shape({
                bar: PropTypes.string.isRequired
            })
        }).isRequired
    ]).isRequired
};

But this gives me the following warning:

Warning: Failed prop type: Invalid prop config of value [object Object] supplied to MyComponent, expected one of [{"active":true},null].

in MyComponent

I know why this does not work: it's because PropTypes.oneOf does not expect dynamic prop type matchers as values, but simply an array of valid arguments.

The question is, is there a way to make this work?

I've made a runnable sandbox example where you can try out the example code above: https://codesandbox.io/s/n9o0wl5zlj

Patrick Hund

As wgcrouch suggested in his answer, the prop-types lib does not provide this functionality, so using a custom prop type is the way to go.

Fortunately, as Tom Fenech pointed out in the comments to my question, this particular problem has already been solved, so there is an npm package available that I've used: react-required-if.

My working solution looks like this:

import React from 'react';
import PropTypes from 'prop-types';
import requiredIf from 'react-required-if';

function MyComponent({ config }) {
  if (!config.active) {
    return null;
  }
  return <h1>Hello {config.foo.bar}!</h1>;
}

MyComponent.propTypes = {
  config: PropTypes.shape({
    active: PropTypes.bool.isRequired,
    foo: requiredIf(
      PropTypes.shape({
        bar: PropTypes.string.isRequired
      }),
      props => props.active
    )
  })
};

export default MyComponent;

→ See updated code sandbox with solution.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

missing in props validation react/prop-types

React - prop-types is marked as required

Dynamic props depending on other prop

Dispatch action is missing in props validation [react/prop-types]

Eslint - 'match' is missing in props validation (react/prop-types)

Line 5: 'tags' is missing in props validation react/prop-types

'children' is missing in props validation react/prop-types

React PropTypes : Allow different types of PropTypes for one prop

Switching between two different prop types in one React component

ESLint: '.map is missing in props validation' (eslint react/prop-types) in Typescript React

Eslint react/prop-types vs react/require-default-props

React call API depending on Props

React interdependent prop types

Checking prop types in React

DRY React method of rendering same props & text to different component types

How to pass a specific prop when the props can have multiple types in React, Typescript?

Should I use the package prop-types or pass a Props interface to React components?

Line 4:27: 'component' is missing in props validation react/prop-types

Reusing a common PropType shape with props required or not required depending on the component

At least one required prop in React

How to pass in props to an element that changes in size depending on prop

Component to return something different depending on props

How to pass props to React child components whose required types we don't know yet

Need to import prop types in React?

prop types not working in react application

React prop-types error

React Prop Types vs Typescript

How to chose a React component props depending on condition

React - How to pass props to a component passed as prop