I made a Christmas gifts list with React and I would like to change the available prop from true to false when a user clicks on "I want to offer this gift" but there is an error and I don't know why. The error is : TypeError: setAvailability is not a function
Here is my Book component:
function Book({available, setAvailability}) {
return (
<div className="gift-item-availability">
{ available ? <p className="gift-item-avail">Available</p> : <p className="gift-item-unavail">Booked</p> }
{ available ? <p className="gift-item-action" onClick={()=> setAvailability(false)}>I want to offer this gift</p> : null }
</div>
)
}
export default Book
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Here is my Gift Component :
import {React, useState} from "react"
import '../styles/GiftItem.css'
import CurrencyFormat from 'react-currency-format';
import Book from "./Book";
function GiftItem({image, name, available, lien1, lien2, lien3, price, category}) {
const setAvailability = useState({available})
return (
<li className='gift-item'>
<CurrencyFormat value={price} displayType={'text'} thousandSeparator={true} suffix={'€'} renderText={value => <div className="gift-item-price">{value}</div>} />
<div className="gift-item-cover">
<img className="gift-item-cover" src={ window.location.origin "/img/" image } alt={ name } />
</div>
<h2 className="gift-item-name">{ name }</h2>
<div className="gift-item-details">
<Book available={available} setAvailability={setAvailability} />
<div className="gift-item-link">
{ lien3 ? <a href={ lien3 } target="_blank" rel="noreferrer"><img src={ window.location.origin "/img/amazon.png"} alt="Amazon" /></a> : null }
{ lien1 ? <a href={ lien1 } target="_blank" rel="noreferrer"><img src={ window.location.origin "/img/picwictoys.png"} alt="Pic Wic Toys" /></a> : null }
{ lien2 ? <a href={ lien2 } target="_blank" rel="noreferrer"><img src={ window.location.origin "/img/king_jouet.png"} alt="King Jouet" /></a> : null }
</div>
</div>
</li>
)
}
export default GiftItem
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
And the complete List Component :
import {React, useState} from "react"
import { giftList } from '../data/giftList'
import '../styles/ShoppingList.css'
import GiftItem from './GiftItem'
import Categories from "./Categories"
function ShoppingList() {
const [activeCategory, setActiveCategory] = useState('')
const categories = giftList.reduce(
(acc, gift) =>
acc.includes(gift.category) ? acc : acc.concat(gift.category),
[]
)
return (
<div className='shopping-list'>
<Categories
categories={categories}
setActiveCategory={setActiveCategory}
activeCategory={activeCategory}
/>
<ul className='gift-list'>
{giftList.map(({image, name, available, lien1, lien2, lien3, price, category}) => (
!activeCategory || activeCategory === category ? (
<GiftItem
image={image}
name={name}
available={available}
lien1={lien1}
lien2={lien2}
lien3={lien3}
price={price}
key={name}
/>
) : null
))}
</ul>
</div>
)
}
export default ShoppingList
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Thanks a lot for your help !!!
CodePudding user response:
The useState
hook returns an array containing two elements, not a function. The first item in the array is the value, the second item is the function used to update that value. Typically you'd destructure it like this:
const [availability, setAvailability] = useState({available})
The useState
documentation has some more helpful information.
CodePudding user response:
It should be const [availability, setAvailability] = useState(true)
;
useState return an array not the function.
you can then use setAvailability(false)
to set availability state as false.