i want to filter the elements that I get on the page, based on the checkbox value(if it's checked or not). For that i have the following code:
import React from 'react'
import CocktailCard from './CocktailCard'
import { useGlobalContext } from '../helpers/context'
export default function Cocktails() {
const isAlcoholic = React.useRef(null);
const {cocktails} = useGlobalContext()
const changeFilter = (isAlcoholic) ? cocktails.filter(cocktail => cocktail.isAlcoholic === "Alcoholic") : cocktails
console.log(changeFilter)
if(cocktails.length < 1) {
return <h2 className="section-title">No cocktails available</h2>
}
return (
<div>
<div className="row">
<div className="form-check">
<label className="form-check-label" htmlFor="alcoholic">
Alcoholic
<input
className="form-check-input"
type="checkbox"
ref={isAlcoholic}
onChange={() => {
changeFilter(isAlcoholic.current.checked);
}}/>
</label>
</div>
</div>
<div className="container">
<div className="row">
{
cocktails.map((item) => {
return <CocktailCard key={item.id} {...item}/>
})
}
</div>
</div>
</div>
)
}
I tried to do changeFilter function so it will filter out the alcoholic one, if not, it will give back the current array. I'm sure I do something wrong, because I get an error in the console saying that changeFilter is not a function.
Can you guys give me a better idea how I should tackle this error and logic in general?
In the component use a boolean for checkbox state.
const [showAlcoholic, setShowAlcoholic] = useState(false);
Continue to filter the list of cocktails depending on the showAlcoholic state. You have logic for that already.
Set state on input changes. For the checkbox:
onChange={event => setShowAlcoholic(event.target.checked)}
You have to use React states in order to get the list of items (in your case, cocktails) updated and the component re-rendered.
This is done with React's useState hook. Everytime the state gets updated, the component is re-rendered.
Note that there is no need for references, and that it can be removed from the input.
You can change your code to this and compare to what you had before. The code could be further improved, but I wanted to keep it closer to what you already had.
export default function Cocktails() {
const [isAlcoholic, setIsAlcoholic] = useState(true);
const { cocktails } = useGlobalContext()
const filteredCocktails = cocktails.filter((coktail) => {
return isAlcoholic ? cocktail => cocktail.isAlcoholic === "Alcoholic" : true;
})
if (cocktails.length < 1) {
return <h2 className="section-title">No cocktails available</h2>
}
return (
<div>
<div className="row">
<div className="form-check">
<label className="form-check-label" htmlFor="alcoholic">
Alcoholic
<input
className="form-check-input"
type="checkbox"
onChange={() => {
setIsAlcoholic(isAlcoholic.current.checked);
}} />
</label>
</div>
</div>
<div className="container">
<div className="row">
{
filteredCocktails.map((item) => {
return <CocktailCard key={item.id} {...item} />
})
}
</div>
</div>
</div>
)
}