Kostiantyn
Kostiantyn

Reputation: 1853

Failed prop type warning in unloaded component

I'm getting a warning for a page that I'm not currently on(being on the https://example.com/this-page).

Warning: Failed prop type: The prop `query` is marked as required in `OtherPage`, but its value is `undefined`.

"prop-types": "^15.7", "react": "^17.0", "react-redux": "^7.2", "react-router-dom": "^6.0",

This component is used directly in the Route component

let global_props = {...}
...
<Routes>
    <Route path="/this-page" exact element={<ThisPage ...{global_props}/>}/>
    <Route path="/other-page" exact element={<OtherPage ...{global_props}/>}/>
</Routes>

Here's the component. Note, it's not using redux at the moment.

import React, {Component} from 'react';
import PropTypes from "prop-types";

class OtherPage extends Component {
    render() {
        return <div>HI</div>;
    }
}

OtherPage.propTypes = {
    query: PropTypes.object.isRequired
};

export default OtherPage;

What would be the reason for that?

Thanks.

Upvotes: 1

Views: 250

Answers (1)

gerrod
gerrod

Reputation: 6627

If that's literally what your routes look like, then you're getting the warning for exactly the reason it says - you're not defining the query property on the <OtherPage /> element.

It doesn't matter if that route is active or not, as far as React is concerned, you're violating the contract that you set, which states that the query property is required. If you're not going to pass the query property, why not make it optional?

Aside - also, the exact property no longer exists on the Route component - via: https://reactrouter.com/docs/en/v6/upgrading/v5#relative-routes-and-links

  • <Route exact> is gone. Instead, routes with descendant routes (defined in other components) use a trailing * in their path to indicate they match deeply

Edit after question update

It's still the same problem - you've said that the query property on <OtherPage /> is required, but you're not guaranteeing that you'll supply the query property to <OtherPage />. If global_props definitely has a query property, then you won't get the error:

const global_props = {
    query: {},
};

// No errors!
return <OtherPage {...global_props} />;

It seems odd that you're marking the property as required if you're not always going to pass the property (which is literally what the error is saying 😀). Your only choices here are to either make the property optional and then deal with undefined in the <OtherPage /> control, or provide a defaultProps.query to cater for it not being passed:

const OtherPage = ({ query }) => {
  // ...
};

OtherPage.defaultProps = {
  query: {}
};

There's a third option too - you've said that global_props might have a query prop and it might not; if you can guarantee that global_props will have the query property anytime that <OtherPage /> is called, you could put a guard around that route -

{global_props.query && (
  <Route path="/other" element={<OtherPage {...global_props} />} />
)}

Here's a code-sandbox you can play with that might help. If you comment out the query property from both defaultProps and global_props then you receive an error; adding either one of them back in will remove the error.

To answer your actual question as to why you're getting this error even though the component isn't loaded: prop-types is just a bunch of validators that check your code when it loads. Think of it more like a compiler warning rather than a runtime warning.

Upvotes: 1

Related Questions