I try to integrate a search page in my application with react router v5.
How could I update my url's query parameter using my search box?
When I refresh my application, I lose my search results and the value of my search field.
I use redux to manage the state of the value of my search fields and my search results, I think that going through the parameters of the url would be a better solution but I do not know how to do that.
I tried a solution (see my code), but the query parameter of the url is not synchronized with the value of my text field
Edit:
My component Routes.js
const Routes = (props) => {
return (
<div>
<Route exact path="/" component={Home} />
<Route
exact
path='/search'
component={() => <Search query={props.text} />}
/>
<Route path="/film/:id" component={MovieDetail} />
<Route path="/FavorisList" component={WatchList} />
<Route path="/search/:search" component={Search} />
<Route path="*" component={NotFound} />
</div>
)}
My component SearchBar.js (Embedded in the navigation bar, the Search route displays the search results)
EDIT:
I wish to realize the method used by Netflix for its research of series.
I want to be able to search no matter what page I am in, if there is an entry in the input field, I navigate to the search
page withthis.props.history.push (`` search /
), if the input field is empty, I navigate to the page with this.props.history.goBack ()
.
The state inputChange is a flag that prevents me from pushing to the search page each time I enter a character.
To know more, I had opened = a post here => How to change the route according to the value of a field
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue:'',
};
}
setParams({ query }) {
const searchParams = new URLSearchParams();
searchParams.set("query", query || "");
return searchParams.toString();
}
handleChange = (event) => {
const query = event.target.value
this.setState({ inputValue: event.target.value})
if (event.target.value === '') {
this.props.history.goBack()
this.setState({ initialChange: true })
return;
}
if(event.target.value.length && this.state.initialChange){
this.setState({
initialChange:false
}, ()=> {
const url = this.setParams({ query: query });
this.props.history.push(`/search?${url}`)
this.search(query)
})
}
}
search = (query) => {
//search results retrieved with redux
this.props.applyInitialResult(query, 1)
}
render() {
return (
<div>
<input
type="text"
value={this.state.inputValue}
placeholder="Search movie..."
className={style.field}
onChange={this.handleChange.bind(this)}
/>
</div>
);
}
export default SearchBar;
Component App.js
class App extends React.Component {
render(){
return (
<div>
<BrowserRouter>
<NavBar />
<Routes/>
</BrowserRouter>
</div>
);
}
}
export default App;
Query for search results (Managed with Redux)
export function applyInitialResult(query, page){
return function(dispatch){
getFilmsFromApiWithSearchedText(query, page).then(data => {
if(page === 1){
dispatch({
type:AT_SEARCH_MOVIE.SETRESULT,
query:query,
payload:data,
})
}
})
}
}