首页 > 解决方案 > 通过删除所有查询参数来响应路由器渲染两次和 URL 更改

问题描述

我正在使用BrowserRouterhistory.push在页面之间导航。我想遍历在第一页输入查询参数的新页面。

即,在主页中,有一个搜索栏,用户在其中输入一些搜索字符串abc,当单击按钮时,我想重定向到另一个页面/search?q=abc

我观察到的是,/search?q=abc它被正确渲染一次,然后它会自动重定向到/search?删除所有查询参数。我无法理解为什么它会渲染两次?

套餐

"react": "^16.12.0",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",

应用程序.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 <- 这是包含搜索栏的第一页

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

历史.js

import { createBrowserHistory } from "history";
export default createBrowserHistory();

我在这里想念什么?

更新

以下是描述行为的上述代码示例: https ://codesandbox.io/s/blissful-fermat-60xzy

标签: javascriptreactjsreact-routerreact-bootstrapreact-component

解决方案


2种方法来解决您的问题:

第一个解决方案:

  • Router不进口BrowserRouter
  • 将您history定义的内容./history.js传递给Router. 像这样<Router history={history}>
  • 现在history.push({.....应该可以按预期工作。

第二种解决方案:

  • 进口BrowserRouter
  • Jumbotron_withRouter
  • 使用this.props.history.push(...)而不是history.push(...)

您的代码(第一个解决方案)的工作副本在这里:

https://codesandbox.io/s/router-issue-page-refresh-after-search-hl849?file=/src/App.js


推荐阅读