0

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?

2 Answers 2

1

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)}
Sign up to request clarification or add additional context in comments.

1 Comment

You were definitely right, thanks a lot.
0

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>
  )
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.