Реагируйте на рендеринг маршрутизатора дважды и измените URL, удалив все параметры запроса - PullRequest
1 голос
/ 19 апреля 2020

Я использую BrowserRouter и history.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 <- это первая страница, содержащая строку поиска </p>

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

1 Ответ

3 голосов
/ 19 апреля 2020

2 способа решить вашу проблему:

Первое решение:

  • импорт Router не BrowserRouter
  • передать ваш history, который вы определили в ./history.js до Router. Вот так <Router history={history}>
  • Теперь history.push({..... должен работать так, как вы ожидаете.

Второе решение:

  • import BrowserRouter
  • Оберните компонент Jumbotron withRouter
  • , используя this.props.history.push(...) вместо history.push(...)

Рабочая копия вашего кода (1-е решение) здесь:

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

...