При нажатии кнопки я получаю изменение URL-адреса, выполняя history.push()
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
.
. some code
.
history.push(`/share/${objectId}`)
и надеясь, что компонент, упомянутый в Route для этого URL-адреса, отобразится, но этого не происходит. Однако при обновлении этот компонент отображается, как и ожидалось. Но я не понимаю, почему он не отображается, как только URL-адрес меняется. Я пробовал завернуть компонент внутрь withRouter.
import React, {Component} from 'react'
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'
import createHistory from 'history/createBrowserHistory'
import Home from './pages/home'
import ViewFile from './pages/view-file'
const history = createHistory()
class App extends Component {
constructor(props) {
super(props)
}
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path = {'/'} component = {Home}/>
<Route path = {'/share/:id'} component = {withRouter(ViewFile)}/>
</Switch>
</BrowserRouter>
)
}
}
export default App
а также передать история в Router, что я думаю так же, как использовать BrowserRouter.
import React, {Component} from 'react'
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'
import createHistory from 'history/createBrowserHistory'
import Home from './pages/home'
import ViewFile from './pages/view-file'
const history = createHistory()
class App extends Component {
constructor(props) {
super(props)
}
render() {
return (
<Router history = {history}>
<Switch>
<Route exact path = {'/'} component = {Home}/>
<Route path = {'/share/:id'} component = {ViewFile}/>
</Switch>
</Router>
)
}
}
export default App
но с этим не повезло. Кто-нибудь может объяснить, почему это происходит?
P.S Просмотрел ответы здесь но они не помогли
какая версия реактивного маршрутизатора?
@Sujit.WarrierIt 4.3.1
См. также: Приложение React показывает пустую страницу при перенаправлении





Вы создаете новую историю каждый раз, когда вызываете createHistory(). Если вы используете react-router-dom, вы можете просто использовать withRouter HOC, который будет передавать объект history компоненту через prop. Затем вы будете использовать history.push('/') или, если он находится в class component, this.props.history.push('/') и так далее.
Рабочий пример: https://codesandbox.io/s/p694ln9j0
маршруты (определить history внутри routes)
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";
const history = createBrowserHistory();
export default () => (
<Router history = {history}>
<div>
<ScrollIntoView>
<Header />
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/about" component = {About} />
<Route path = "/contact" component = {Contact} />
</Switch>
<Header />
</ScrollIntoView>
</div>
</Router>
);
компоненты/Header.js (мы хотим получить доступ к history, однако иногда нам приходится использовать withRouter, потому что такие компоненты, как Header, не находятся в <Route "/example" component = {Header}/> HOC, поэтому он не знает о нашей маршрутизации)
import React from "react";
import { withRouter } from "react-router-dom";
const Header = ({ history }) => (
<header>
<nav style = {{ textAlign: "center" }}>
<ul style = {{ listStyleType: "none" }}>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/")}>Home</button>
</li>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/about")}>About</button>
</li>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/contact")}>Contact</button>
</li>
</ul>
</nav>
</header>
);
export default withRouter(Header);
компоненты/Home.js (такой компонент, как Home, знает о маршрутизации и имеет объект history, уже переданный через <Route path = "/" component = {Home} /> HOC, поэтому withRouter не требуется)
import React from "react";
const Home = ({ history }) => (
<div className = "container">
<button
className = "uk-button uk-button-danger"
onClick = {() => history.push("/notfound")}
>
Not Found
</button>
<p>
...
</p>
</div>
);
export default Home;
Та же концепция, что и выше, однако, если вы не хотите использовать withRouter, вы можете просто создать экземпляр history, который будет использоваться всеми вашими компонентами, которым он нужен. Вы будете import этот history экземпляр и будете перемещаться с помощью history.push('/'); и так далее.
Рабочий пример: https://codesandbox.io/s/5ymj657k1k
история (определить history в собственном файле)
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
export default history;
маршруты (импортировать history в routes)
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";
import history from "../history";
export default () => (
<Router history = {history}>
<div>
<ScrollIntoView>
<Header />
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/about" component = {About} />
<Route path = "/contact" component = {Contact} />
</Switch>
<Header />
</ScrollIntoView>
</div>
</Router>
);
компоненты/Header.js (импортировать history в Header)
import React from "react";
import history from "../history";
const Header = () => (
<header>
<nav style = {{ textAlign: "center" }}>
<ul style = {{ listStyleType: "none" }}>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/")}>Home</button>
</li>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/about")}>About</button>
</li>
<li style = {{ display: "inline", marginRight: 20 }}>
<button onClick = {() => history.push("/contact")}>Contact</button>
</li>
</ul>
</nav>
</header>
);
export default Header;
компоненты/Home.js (по-прежнему знает о маршрутизации и имеет объект history, уже переданный через <Route path = "/" component = {Home} /> HOC, поэтому импорт history не требуется, но вы все равно можете импортировать его, если хотите — просто не разбирайте history в Home' параметры функции)
import React from "react";
const Home = ({ history }) => (
<div className = "container">
<button
className = "uk-button uk-button-danger"
onClick = {() => history.push("/notfound")}
>
Not Found
</button>
<p>
...
</p>
</div>
);
export default Home;
Но вы можете подумать, а как насчет BrowserRouter? Ну, у BrowserRouter есть свой внутренний history объект. Мы снова можем использовать withRouter для доступа к его history. В этом случае нам даже не нужно createHistory() вообще!
Рабочий пример: https://codesandbox.io/s/ko8pkzvx0o
маршруты
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import Notfound from "../components/Notfound";
import ScrollIntoView from "../components/ScrollIntoView";
export default () => (
<BrowserRouter>
<div>
<ScrollIntoView>
<Header />
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/about" component = {About} />
<Route path = "/contact" component = {Contact} />
<Route component = {Notfound} />
</Switch>
<Header />
</ScrollIntoView>
</div>
</BrowserRouter>
);
Большое спасибо. Вчера я потратил часы на чтение документации по реактивному маршрутизатору, но мало что понял. Я думаю, вы должны были написать документы.
Это не работает, я понятия не имею, почему, я использую Router, а не BrowserRouter, но все мои компоненты не отображаются, URL-адрес меняется, но я всегда получаю компонент резервного маршрута 404.
@HassanAzzam Создайте MCVE, а затем задать новый вопрос с вашим примером кода.
Это точно такой же код выше, и он не работает, я даже пробовал history.listen, и он возвращает undefined, когда я меняю маршруты.
@HassanAzzam Похоже, они отказались от поддержки использования вашего собственного объекта истории в v5. Когда это было написано, v4.x.x была последней, и поэтому она работает как ожидал. Я бы посоветовал вам отказаться от этого подхода, так как есть другие лучшие альтернативы (например, использование BrowserRouter либо с хуком useHistory, либо доступ к history с помощью компонента более высокого порядка withRouter, если вы не используете хуки).
Или... если вы используете redux, то используйте подключенный реактивный маршрутизатор, что позволяет вам push или replace элементы в истории из любого места.
Да, я знаю, но проблема в том, что я хотел использовать его вне компонента, а useHistory работает только внутри компонента. Но в любом случае спасибо за разъяснение, вы сэкономили мне много времени.
проверьте версию react , react-router, react-router-dom и версию пакета истории, которая также бессильна
Я просто удивляюсь, почему эти вещи не стандартизированы. Почему всем приходится бороться.
Несколько моментов:
1) Используйте import { Router} from 'react-router-dom' вместо import { BrowserRouter as Router} from 'react-router-dom'
2) Создайте переменную history в другом файле, а именно (можно изменить) ../src/services/history.js и содержание должно быть:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;
Вам нужно будет установить пакет react-history до npm install --save react-history
3) Импортируйте историю в основной файл и передайте ее внутри компонента Router.
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom'
import history from './services/history'
class App extends React.Component {
render() {
return (
<Router history = {history}>
<Switch>
<Route exact path='/' component = {MainPage}></Route>
<Route exact path='/vendor' component = {VendorPage}></Route>
<Route exact path='/client' component = {ClientPage}></Route>
</Switch>
</Router>
);
}
}
export default App;
4) Теперь вы можете использовать history в любом месте компонентов,
import React from 'react'
import history from '../services/history';
export default class VendorPage extends React.Component {
loginUser = () => {
if (<SOME_CONDITION>)
history.push('/client')
}
render() {
return (
<h1>Welcome to Vendor Page....</h1>
)
}
}
Надеюсь, поможет..
:)
Я думаю, что он может useHistory() крючок react-router-dom, так что ему не придется устанавливать другую библиотеку.
к сожалению, это больше не работает
Это не работает ожидаемым образом для react-router-dom v6
используйте import { Router } вместо import { BrowserRouter as Router } .
Поскольку BrowserRouter игнорирует реквизит истории.
Ух ты! Вот оно! Столько часов пытался найти это! history.push() точно так же работает с Router.
Вау, это проще, чем я думал. Спасибо!
Установка BrowserRouter prod forceRefresh на true также работает. <BrowserRouter forceRefresh = {true}>
Это может кому-то помочь. Убедитесь, что версия пакета history совместима с версией react-router-dom.
Эта комбинация не работает для меня:
история: 5.0.0 с реактивным роутером: 5.2.0
Это комбо сделал:
история: 4.10.1 с реактивным роутером 5.2.0
Спасибо! Я была такая же проблема.
+1 это сработало для меня. У меня была история в v 5.0.0 и точно такой же react-router-dom в 5.2.0!!! Спасибо! Спас мой день ;)
Большое спасибо! Целый день искал этот ответ!!!
Спасибо! Оно работало завораживающе
проверить версию react, react-router, react-router-dom и версию пакета history, которая также бесполезна – моя конфигурация package.json
"history": "^4.10.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router": "5.1.2",
"react-router-dom": "5.1.2"
проверьте эту ссылку: - https://stackblitz.com/edit/react-34ohqv?embed=1&file=package.jsonhttps://stackblitz.com/edit/react-router-example-mahi-hzitgg?embed=1&file=index.js
Потратил 3 часа на то, почему история не работала, вот в чем причина. Спасибо!
Точно!!! Почему-то версия истории 5 не работает! Когда я понизил версию до предложенной версии, все работало нормально. Спасибо!
Для люди, использующие хуки сработало использование хука useLocation() вместо useHistory().
const { pathname } = useLocation();
Компонент перерисовывается каждый раз, когда изменяется путь.
Понижение пакета истории до истории: у меня работает 4.10.1 с react-router-dom 5.2.0
Использовать этот:
import { useHistory, useRouteMatch } from 'react-router-dom';
let history = useHistory();
let match = useRouteMatch();
Можете ли вы вставить больше кода, касающегося места, где вы звоните: history.push(
/share/${objectId})