0

I have a component which gathers an array of ingredients from a user input.
I am trying to send this state array as props to another component, onclick, when I click a 'search' button.
However, I cannot get the props to pass and don't know what to do.

SearchBar component:

import React, { useState, useEffect } from 'react'
import MultiSearch from '../MultiSearch';

const SearchBar = () => {
  const [ingredients, setIngredients] = useState([])
  const [filteredData, setFilteredData] = useState([])
  
  const [fetchData, setFetchData] = useState([])

  const searchWordInput = document.querySelector('#search-word')


  const handleFilter = (e) => {
    const searchWord = e.target.value
    const newFilter = ingredients.filter((value) => {
      return value.strIngredient1.toLowerCase().includes(searchWord.toLowerCase())
    })
    if (searchWord === "") {
      setFilteredData([])
    } else {
    setFilteredData(newFilter)
    }
  } 


  useEffect(() => {
      fetch("https://www.thecocktaildb.com/api/json/v2/9973533/list.php?i=list")
      .then((resp) => resp.json())
      .then((data) => {
          setIngredients(data.drinks)
      })
  }, [])

  const handleIngredientSelect = (e) => {
    const selected = e.target.textContent
    searchWordInput.value = selected
  }

  const handleAddIngredient = () => {
    setIngredientsSelected([...ingredientsSelected, searchWordInput.value])
    console.log(ingredientsSelected)
    searchWordInput.value = ""
  }

  const passIngredients = (ingredientsSelected) => {
      <MultiSearch ingredients={ingredientsSelected} />
      console.log('Searched!')
  }
console.log(ingredientsSelected)
  return (
    <div className="search">
    <div className="searchInputs">
        <input id="search-word" type="text" placeholder='Enter ingredient' onInput={handleFilter} />
        <input onClick={handleAddIngredient} type="button" value="add ingredient" id="submit-btn"/>
        <input onClick={passIngredients} type="submit" value="search!"/>
        <div className="searchIcon"> 
        </div>    
    </div>
    {filteredData.length !== 0 && (
    <div className="dataResult">
      {filteredData.map((value, key) => {;    
                return (
                    <div key={key} className='dataItem'>
                        <p onClick={handleIngredientSelect} id="ingredient">{value.strIngredient1} </p> 
                    </div>
                );
            })}  
    </div>
)}
</div>
  )
}

export default SearchBar


Page which renders the two components:
import React from 'react'
import MultiSearch from '../../components/MultiSearch'
import SearchBar from '../../components/SearchBar'

function Search() {
  return (
    <>
        <SearchBar />
        <MultiSearch />
    </>
  )
}

export default Search

Component to receive the props:

function MultiSearch(ingredients) {
    console.log(ingredients)

etc... the props never get logged

2
  • 3
    You need "Lift the state up", since data in React "flows down", search both terms in React docs for explanations Commented May 24, 2022 at 17:33
  • btw. the multisearch in the function passIngredients on the Searchbar component is not the same as the multisearch you are rendering in Search() <MultiSearch /> Commented May 24, 2022 at 17:40

1 Answer 1

1

You would have to move your state to the parent component of both child components.

import React from 'react'
import MultiSearch from '../../components/MultiSearch'
import SearchBar from '../../components/SearchBar'

function Search() {
  const [ingredients, setIngredients] = useState()

  return (
    <>
        <SearchBar setIngredients={setIngredients} />
        <MultiSearch ingredients={ingredients} />
    </>
  )
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Bart, but the props I want to pass to MultiSearch is ingredientsSelected. I am unsure what I need to change in my other code.. I have edited the post to show the full code now
Still, you need to move your state up. You can leave the ingredients state in the SearchBar component, but you'd need to move the filteredData state to the parent component. Then you can pass the setter with prop: ``` const [filteredData, setFilteredData] = useState([]) ... <SearchBar setFilteredData={setFilteredData} /> ```

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.