Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better prop types warnings #279

Open
goldylucks opened this issue Jul 6, 2019 · 15 comments
Open

Better prop types warnings #279

goldylucks opened this issue Jul 6, 2019 · 15 comments

Comments

@goldylucks
Copy link

Do you want to request a feature or report a bug?
Request a feature

What is the current behavior?
React prop types warning doesn't reveal info on the component's instance

What is the expected behavior?
Print also the component's props

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
N/A

The current warnings point the developer only to the source code, and it would be AMAZING if we'll easily see which component instance caused the warnings. Consider a list with hundreds of items, each rendering a component. ATM there's no convenient way to track down the renegade instance.

So instead of the current behavior:

image

Also add:

index.js:1375 Warning: Failed prop type: The prop `latitude` is marked as required in `RestaurantListItem`, but its value is `null`.

RestaurantListItem's instance has the following props: {OBJECT_OF_PROPS_THAT_OPENS_ON_CLICK}

I currently find myself many times having to temporary do this in different components.

It seems to me like a very easy thing to add, at least for a development build.

Thoughts?

I can take a swing at it with some guidance (I'd love to dip my toes in React's code)

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

Browsers don't offer the API for "object that opens on click" embedded in the message in a reliable cross-browser way, and what would happen on node?

@goldylucks
Copy link
Author

object that opens on click is default behavior on chrome. it's not like that cross library?

If we can console everything as independent arguments instead of a string, wouldn't it work?

Also here are some ideas for a first step to check the validity of this direction:

  1. json strongify the entire component's instance props and append/prepend that to the warning message
  2. try to find a common identifier prop name by iterating over the props, i.e. id || name || title || text
  3. allow defining something like static missingPropTypeIdentifier = id on the class
  4. allow defining something like `PropTypes.configure({ missingPropTypeIdentifiers: ["id", "name", "title", "text"]

what do you think?

I'm doing this currently in my code and so far it works great:

image

I have a list of hundreds of restaurants, and immediately I know which one is missing the prop. Here's the code for that:

import PropTypes from 'prop-types'

// eslint-disable-next-line import/prefer-default-export
export const reportMissingProps = (Component, componentInstance) => {
  if (!Component.propTypes) {
    console.warn('[Report missing props] -> propTypes empty -> bailing')
    return
  }
  // see https://github.com/facebook/react/issues/16069
  PropTypes.checkPropTypes(
    Component.propTypes,
    componentInstance.props,
    'prop',
    `${Component.name} -> ${identifyingProps(componentInstance)}`
  )
}

function identifyingProps(componentInstance) {
  const {
    props: { id, name, title },
  } = componentInstance
  return id || name || title
}

What do you think @ljharb ?

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

It's definitely not like that in every browser, and it's definitely not like that in node, which is text only.

Separately, not every browser (or every supported version of every browser) supports more than one argument to console.log.

What I'm confused about is how you have so many instances of the same component. but that aren't defined in the same place in code (ie, in a .map or similar). What does your code look like that it's even possible to omit passing the prop to just one instance?

@goldylucks
Copy link
Author

It's definitely not like that in every browser, and it's definitely not like that in node, which is text only.

Gotcha, thanks for educating me on this, I forget sometimes there's a world outside of chrome 🤦‍♂️

Separately, not every browser (or every supported version of every browser) supports more than one argument to console.log.

That's perfectly fine, we can print everything directly as a string in the console. We can also call console.log multiple times.

What does your code look like that it's even possible to omit passing the prop to just one instance?

I get some of the data from an external API, which has hiccups. So I get back an array of hundreds of items, and one of them is missing the latitude property. Makes sense?

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

We can't call console.log more than once for a single error; that would pollute the log for people.

It sounds like what you really need is to validate the data before passing it into the react tree - using something like jsonschema, perhaps?

@goldylucks
Copy link
Author

indeed, I can use many strategies to validate data on my end. But why not improve the developer experience of all React's users?

Do you see any drawbacks in printing extra 3-6 characters in the prop warning in order to identify the instance?

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

I'm claiming that it's not in fact all of React's users - that typically, either the API has correct data, or everyone validates it.

I see drawbacks in adding complexity and performance overhead.

@goldylucks
Copy link
Author

goldylucks commented Jul 6, 2019

I can't imagine I'm the only developer who stumbled upon this, but who knows.

performance overhead

why is that? it's only in development, and only when there's an error to report, otherwise the extra function call to print the identifier won't be called.

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

Development has to perform well too.

@goldylucks
Copy link
Author

only when there's an error to report

so there's no impact to development unless there are prop type errors, in which case the developer will fix it anyway.

So how does this hurts performance?

@ljharb
Copy link
Collaborator

ljharb commented Jul 6, 2019

Prop type errors don’t interrupt rendering, by design - devs don’t have to fix them and their app needs to keep working the same.

@asbjornh
Copy link

asbjornh commented Aug 5, 2019

Using arbitrary keys like id, name and so on seems a bit weird, and so does dumping JSON strings or object literals to the "console". But maybe outputting the key (when it exists) directly in the error message could help without adding too much overhead?

Warning: Failed prop type: The prop 'blabla' is marked as required in 'SomeComponent' with key 'abc', but its value is 'null'.

@goldylucks
Copy link
Author

goldylucks commented Aug 5, 2019 via email

@ljharb
Copy link
Collaborator

ljharb commented Aug 6, 2019

@asbjornh if you want to try submitting a PR, that seems like it might be worth exploring.

@asbjornh
Copy link

asbjornh commented Aug 6, 2019

@ljharb I made a draft PR because I'm not feeling super confident about the idea anymore

@ljharb ljharb changed the title Better prop types warnigs Better prop types warnings Aug 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants