I am using BrowserRouter
and history.push
to navigate between pages. I want to traverse to a new page with query parameters entered in the first page.
i.e., in the homepage, there is a search bar where user enters some search string abc
, and when the button is clicked, I want to redirect to another page /search?q=abc
What I observed is, the /search?q=abc
is rendered properly once and then it automatically redirects to /search?
dropping all the query parameters. I am not able to understand why is it rendering twice?
Packages
"react": "^16.12.0",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
App.js
import React, { Component} from 'react';
import './App.css';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import Jumbotron from "./component/Jumbotron";
const SearchPage = ({ match, location }) => {
return (
<p>
<strong>Query Params: </strong>
{location.search}
</p>
);
};
const HomePage = () => {
return (
<div className="d-flex flex-column">
<div className="container-fluid">
<Jumbotron/>
</div>
</div>
)
};
class App extends Component {
render() {
return (
<Router>
<Route exact={true} path='/' render={HomePage}/>
<Route exact path="/search" render={SearchPage} />
</Router>
);
}
}
export default App;
Jumbotron.jsx <- this is the first page containing search bar
import React, { Component } from 'react';
import { withRouter } from 'react-router';
import history from "../utils/history";
class Jumbotron extends Component {
handleSubmit = () => {
history.push({
pathname: '/search',
search: '?q=' + this.state.query
})
};
handleChange = e => {
this.setState({query: e.target.value});
console.log(e.target.value)
};
render() {
return (<>
<div className="d-flex jumbotron">
<div className="align-self-center container mx-auto">
<br/>
<div>
</div>
<div className="align-self-center">
<form className="d-flex justify-content-center form-inline my-2 my-lg-0">
<input className="search-input col-md-6 mb-3 form-control"
type="search"
placeholder="Type the address here"
aria-label="Search"
onChange={this.handleChange}
/>
<button className="search-btn col-md-1 mb-3 btn btn-primary"
onClick={this.handleSubmit}>Search
</button>
</form>
</div>
</div>
</div>
</>
)
}
}
export default withRouter(Jumbotron);
history.js
import { createBrowserHistory } from "history";
export default createBrowserHistory();
What am I missing here?
UPDATE
Here is an example with the above code that depicts the behavior: https://codesandbox.io/s/blissful-fermat-60xzy
2 ways to solve your issue:
First solution:
Router
not BrowserRouter
history
that you have defined in ./history.js
to the Router
. Like this <Router history={history}>
history.push({.....
should work as you expected.Second solution:
BrowserRouter
Jumbotron
component with withRouter
this.props.history.push(...)
instead of history.push(...)
Working copy of your code(1st solution) is here:
https://codesandbox.io/s/router-issue-page-refresh-after-search-hl849?file=/src/App.js
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加