Uncaught TypeError: Невозможно прочитать свойство 'push' из неопределенного (React-Router-Dom)
У меня есть панель инструментов с вращающимися слайдами, каждая из которых имеет соответствующую вкладку в Bldgs. И то и другое Dashboard.js
а также Bldgs.js
дети для меня App.js
,
Когда пользователь нажимает на определенный слайд A
в Dashboard.js
, Dashboard
нужно сказать App.js
чтобы App
могу сказать Bldgs.js
иметь вкладку A
отображается, когда он направляется в Bldgs
,
Я считаю, что я передаю правильное значение индекса из Dashboard
вплоть до App
и до Bldgs
, Тем не менее, ошибка в моем App.js
файл с указанием:
Uncaught TypeError: Cannot read property 'push' of undefined
Мой код работал нормально, прежде чем я начал передавать handleClick()
функция к моему Dashboard
составная часть.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import injectTapEventPlugin from 'react-tap-event-plugin';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { BrowserRouter as Router } from 'react-router-dom';
import { hashHistory } from 'react-router';
// Needed for onTouchTap
// http://stackru.com/a/34015469/988941
injectTapEventPlugin();
ReactDOM.render(
<MuiThemeProvider>
<Router history={hashHistory}>
<App />
</Router>
</MuiThemeProvider>,
document.getElementById('root')
);
App.js
import React from 'react';
import { Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Bldgs from './Bldgs';
var selectedTab;
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
selectedTab = 0;
}
handleClick(value) {
selectedTab = value;
// console.log(selectedTab);
this.props.history.push('/Bldgs');
// console.log(this.props);
}
render() {
var _this = this;
return (
<div>
<Route exact path="/" render={(props) => <Dashboard {...props} handleClick={_this.handleClick} />} />
<Route path="/Bldgs" component={Bldgs} curTab={selectedTab} />
</div>
);
}
}
export default App;
Dashboard.js
import React, { Component } from 'react';
import './Dashboard.css';
import { AutoRotatingCarousel, Slide } from 'material-auto-rotating-carousel';
...
var curIndex;
class Dashboard extends Component {
constructor(props) {
super(props);
this.handleEnter = this.handleEnter.bind(this);
this.handleChange = this.handleChange.bind(this);
curIndex = 0;
}
handleEnter(e) {
// console.log(curIndex);
this.props.handleClick(curIndex);
}
handleChange(value) {
// console.log(value);
curIndex = value;
}
...
}
export default Dashboard;
Bldgs.js
...
var curTab;
class Bldgs extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.goHome = this.goHome.bind(this);
curTab = 0;
}
handleChange(value) {
this.setState({'selectedTab': value});
console.log(this.state);
}
goHome(e) {
this.props.history.push('/');
}
...
}
export default Bldgs;
7 ответов
Для того, чтобы использовать history
в App
компонент использовать его с withRouter
, Вы должны использовать withRouter
только когда ваш компонент не получает Router props
,
Это может происходить в тех случаях, когда ваш компонент является вложенным дочерним элементом компонента, отображаемого маршрутизатором, или вы не передали ему реквизиты маршрутизатора, или когда компонент вообще не связан с маршрутизатором и отображается как отдельный компонент от Маршруты.
import React from 'react';
import { Route , withRouter} from 'react-router-dom';
import Dashboard from './Dashboard';
import Bldgs from './Bldgs';
var selectedTab;
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
selectedTab = 0;
}
handleClick(value) {
selectedTab = value;
// console.log(selectedTab);
this.props.history.push('/Bldgs');
// console.log(this.props);
}
render() {
var _this = this;
return (
<div>
<Route exact path="/" render={(props) => <Dashboard {...props} handleClick={_this.handleClick} />} />
<Route path="/Bldgs" component={Bldgs} curTab={selectedTab} />
</div>
);
}
}
export default withRouter(App);
Документация по с Роутер
для React-router V4 измените функцию на
OnClick={this.fun.bind(это)}
fun(){
this.props.history.push("/Home");
}
а также
import {browserHistory,withRouter} from "react-router-dom"
export default withRouter (comp_name);
Мы можем использовать useHistory() для истории, чтобы протолкнуть метод
import { useHistory } from "react-router-dom";
а затем в функции мы должны назначить useHistory()
let history = useHistory();
Теперь мы можем использовать history.push для перехода на нужную страницу.
history.push('/asdfg')
Моя ошибка была неправильным смыслом в сочетании с
BrowserRouter
, то есть:
неверно:
import { useHistory } from 'react-router'
верный:
import { useHistory } from 'react-router-dom'
Вы пытаетесь выдать задание действительной библиотеке. на App.js
Итак: на App.js
Вы используете BrowserRouter, который по умолчанию обрабатывает историю страниц, с помощью этой функции response-router-dom вы полагаетесь на BrowserRouter, чтобы сделать это для вас.
Используйте Router вместо BrowserRouter, чтобы получить контроль над своей историей, используйте историю, чтобы контролировать поведение.
- Использовать историю npm "yarn add history@4.xx" / "npm i history@4.xx"
- импортировать маршрут из'act-router-dom'; // не использовать BrowserRouter
- импортировать createBrowserHistory из 'createBrowserHistory';
Не забудьте вывезти это!! экспорт const history = createBrowserHistory ();
4. импортировать историю в Dashboard.js 5. импортировать историю в Bldgs.js
надеюсь это поможет!!! @brunomiyamotto
Я решил эту ошибку, обернув компонент внутри BrowserRouter.
Не забывайте об этом, это очень распространенная ошибка.
import { BrowserRouter} from 'react-router-dom';
<BrowserRouter>
<Menu/>
<BrowserRouter>
Только дети маршрутизатора получают перехватчик истории.
Смотрите мой файл App.js ниже. Я кончил {...this.props}
к компоненту NavBar, который я создал. Компонент NavBar не является частью моих маршрутов коммутатора.
import React, { Component } from 'react';
import { Route, Link, Redirect, Switch, withRouter } from 'react-router-dom'
import Navbar from './Navbar.js';
import Home from './Home/HomeCont';
import Login from './Register/Login';
import Dashboard from './Dashboard/DashboardCont';
import './App.css';
class App extends Component {
constructor(props){
super(props);
}
render() {
return (
<div className="App">
<header className="App-header">
//SOLUTION!!!
<Navbar {...this.props}/>
</header>
<Switch>
<React.Fragment>
<Route exact path="/" render={(props) => <Home {...props}/>}/>
<Route exact path="/login" render={(props) => <Login {...props}/>}/>
</React.Fragment>
</Switch>
</div>
);
}
}
export default withRouter(App);
Внутри моего Навбара. Кнопка, которую я использовал, имела следующий код. Мне пришлось.bind(это), чтобы увидеть историю и быть в состоянии пользователя this.props.history.push("/")
<Button
color="inherit"
onClick={this.handleLogout.bind(this)}>Logout</Button>