Home > Net >  React TypeError: setAvailability is not a function
React TypeError: setAvailability is not a function

Time:11-20

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.

  • Related