简体   繁体   中英

React PropType with ESLint

Started using ESLint and running into couple of issues with PropType, currently I have a prop children and for now let's say this prop is a string . I'm getting an error 'children' is missing in props validationeslint(react/prop-types) , to solve this I just use PropTypes like so:

CartProvider.propTypes = {
  children: PropTypes.string,
}

The above solves the issue and then I get another issue propType "children" is not required, but has no corresponding defaultProps declaration.eslint(react/require-default-props)

So to solve this I add another PropType like so:

CartProvider.defaultProps = {
  children: PropTypes.string,
}

So my understanding is that every time I use a prop I need to use propType and defaultProps . So ok this solves the issue with string based prop. But actually this prop is an array and then with array I'm getting other issues Prop type array is forbiddeneslint(react/forbid-prop-types) .

Please help me understand why does ESLint marking these props as errors, I know how to disabled it but I would like to understand why it's happening and then write better code.

Here is a sample project:

CartContext

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

export const CartContext = React.createContext(null)

export const CartProvider = ({ children }) => {
  const [cartTotal, setCartTotal] = React.useState(0)
  const incrementCartTotal = () => setCartTotal(cartTotal + 1)

  return (
    <CartContext.Provider
      value={{
        cartTotal,
        incrementCartTotal,
      }}
    >
      {children}
    </CartContext.Provider>
  )
}

CartProvider.propTypes = {
  children: PropTypes.string,
}

CartProvider.defaultProps = {
  children: PropTypes.string,
}

App

import React from 'react'
import { CartContext, CartProvider } from './CartContext'

function CartTotalItems() {
  const { cartTotal } = React.useContext(CartContext)
  return (
    <p>
      Total items currently in cart:
      {cartTotal}
    </p>
  )
}

function AddToCart() {
  const { incrementCartTotal } = React.useContext(CartContext)
  return (
    <button type="button" onClick={incrementCartTotal}>
      Add to cart
    </button>
  )
}

export default function App() {
  return (
    <CartProvider>
      <CartTotalItems />
      <AddToCart />
    </CartProvider>
  )
}

Update This has worked for me, remove the 2 PropTypes and add this:

CartProvider.propTypes = {
  children: PropTypes.node.isRequired,
}

You are mistaking the type of children and confuses the use of defaultProps :

// Use for initial value
CartProvider.defaultProps = {
  counter: 10,

/* 
  You declared the initial value to be the value of `PropTypes.string`
  children: PropTypes.string
*/
}
// Children are always an Array of `ReactElement`/ `ReactElement` node.
CartProvider.propTypes = {
  counter: PropTypes.number,

  children: PropTypes.node.isRequired,

/* Same
  children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node
    ]).isRequired
*/

/*
  props.children can't be a string.
  children: PropTypes.string,
*/
}

defaultProps should be set a value instead of using Proptypes again

CartProvider.propTypes = {
  children: PropTypes.string,
}

CartProvider.defaultProps = {
  children: "This is chidlren default string"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM