I have a searchbar component and a Catalog component. The Catalog component contains different cards. Depending on what is typed in the input field of the searchbar component I want to render different cards.
For this to work I need to be able to import the value of the input field into the Catalog component where it is passed in a search function that handles all the rest of the work.
I am able to import the value into my Catalog component but unfortunaty I can't figure out how I can tell if the imported value has changed so I can search again?
I have found some ways to do this with classes but I would like to use hooks instead. I have experimented a bit with "useEffect" but that didn't work out.
Thank you for your help!
This is my code in the searchbar component:
import React, { useState } from 'react';
let input = "";
function Search() {
const [value, setValue] = useState(input);
function onSearch(e) {
setValue(e.target.value);
input = value;
}
return(
<form className="searchForm">
<input className="search" type="text" name="search" autoComplete="off" placeholder="zoeken" value={value} onChange={onSearch}/> </form>
);
}
export { Search, input };
And this is the code in my Catalog
import React, { useState, useEffect } from 'react';
import {input} from "./search";
// other imports
function Catalog(props){
//get cards code and fuse code
const [query, setQuery] = useState(input);
function inputHasChanged(){ //function that can tell if the imported input variable changed
setQuery(input); //update query and rerender cards
}
const results = fuse.search(query)
const searchedCards = query ? results.map(card => card.item) : cards;
//other code
return(
<div>
//render the SearchedCards
</div>
);
}
export {Catalog};
Solution:
code in search:
import React, { useState } from 'react';
const Search = ({ searching }) => {
const [value, setValue] = useState("");
function submit(e){
setValue(e.target.value);
searching(value);
}
return (
<form className="searchForm">
<input
className="search"
type="text" name="search"
autoComplete="off"
placeholder="zoeken"
value={value}
onChange={submit}
/>
</form>
);
};
export { Search };
Search is a child of banner:
import React, {useState, useEffect} from 'react';
import {Search} from './search';
import Header from './Header';
import Overzicht from './Overzicht';
const Banner = ({ search }) => {
const [value, setValue] = useState("");
useEffect(() => {
search(value);
},[search, value]);
return(
<div className="banner">
<Header />
<Search searching={value => setValue(value)} />
<Overzicht />
</div>
);
};
export default Banner;
Banner is a child of home which also contains Catalog:
import React, { useState } from "react";
import Banner from './banner';
import {Catalog} from './Catalog';
function Home(){
const [input, setInput] = useState("");
return(
<div>
<section id="banner">
<Banner search={input => setInput(input)}/>
</section>
<section id="overzicht">
<Catalog search={input} />
</section>
</div>
);
}
export default Home;
And now I can just call
props.search
In Catalog
Push the common state, the query
, up to a common ancestor and pass it down as needed to child and descendant components. This way they can "watch" the changes by having new props passed to them.
Below is a simplified version of a structure that would work:
function Catalog({ query }) {
const [results, setResults] = useState(null);
useEffect(() => {
// If `fuse.search` is asynchronous then you might need to debounce
// these queries and/or cancel old queries. If a user types "foo",
// a query is kicked off, and then they finish typing "food", you
// want to cancel the query for "foo" because the results will no
// longer be relevant.
const results = fuse.search(query);
setResults(results);
}, [query])
return (
<div />
);
}
function Search({ query, setQuery }) {
return (
<input onChange={setQuery} value={query} />
)
}
function App() {
const [query, setQuery] = useState("");
return (
<>
<Search query={query} setQuery={setQuery} />
<Catalog query={query} />
</>
);
}
You can use useEffect as mentioned below:
useEffect(() => { // Write your logic here
},[input]); // it will run only when the input changes
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.