Reputation: 2008
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
arrayis 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,
}
Upvotes: 5
Views: 6093
Reputation: 2931
defaultProps should be set a value instead of using Proptypes again
CartProvider.propTypes = {
children: PropTypes.string,
}
CartProvider.defaultProps = {
children: "This is chidlren default string"
}
Upvotes: 1
Reputation: 53884
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,
*/
}
Upvotes: 2