browserHistory.Push
を使用してプログラムでページを変更しようとしています。私のコンポーネントの1つにありますが、その中に埋め込まれたコンポーネントにはありません。
誰かが私のコンポーネントが親コンポーネントではなく子コンポーネントに対してのみ以下のエラーをスローする理由を知っていますか?
未定義のプロパティ「プッシュ」を読み取ることができません
親コンポーネント
import React, {Component} from 'react';
import { browserHistory } from 'react-router';
import ChildView from './ChildView';
class ParentView extends Component {
constructor(props) {
super(props);
this.addEvent = this.addEvent.bind(this);
}
changePage() {
this.props.history.Push("/someNewPage");
}
render() {
return (
<div>
<div>
<button onClick={this.changePage}>Go to a New Page!</button>
</div>
<ChildView /> // this is the child component where this.props.history.Push doesn't work
</div>
);
}
}
function mapStateToProps(state) {
return {
user: state.user
};
}
function matchDispatchToProps(dispatch) {
return bindActionCreators({
setName: setName
}, dispatch)
}
export default connect(mapStateToProps, matchDispatchToProps)(ParentView);
子コンポーネント
import React, {Component} from 'react';
import { browserHistory } from 'react-router';
class ChildView extends Component {
constructor(props) {
super(props);
this.addEvent = this.addEvent.bind(this);
}
changePage() {
this.props.history.Push("/someNewPage");
}
render() {
return (
<div>
<div>
<button onClick={this.changePage}>Go to a New Page!</button>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
user: state.user
};
}
function matchDispatchToProps(dispatch) {
return bindActionCreators({
setName: setName
}, dispatch)
}
export default connect(mapStateToProps, matchDispatchToProps)(ChildView);
ルーター
// Libraries
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { browserHistory } from 'react-router';
// Components
import NotFound from './components/NotFound';
import ParentView from './components/ParentView';
import ChildView from './components/ChildView';
import SomeNewPage from './components/SomeNewPage';
// Redux
import { Provider } from 'react-redux';
import {createStore} from 'redux';
import allReducers from './reducers';
const store = createStore(
allReducers,
window.devToolsExtension && window.devToolsExtension()
);
const routes = (
<Router history={browserHistory}>
<div>
<Provider store={store}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/parentView" component={ParentView} />
<Route path="/someNewPage" component={SomeNewPage} />
<Route path="/childView" component={ChildView} />
<Route component={NotFound} />
</Switch>
</Provider>
</div>
</Router>
);
export default routes;
ご覧のとおり、コンポーネントは、子コンポーネントが親コンポーネントの内部にあることを除いて、実質的にまったく同じです。
注:これらのアプローチを試しましたが、問題は解決しません。
質問で質問に答えました。
ご覧のとおり、コンポーネントは、子コンポーネントが親コンポーネントの内部にあることを除いて、実質的にまったく同じです。
コンポーネントがさらにネストされているという事実はあなたの問題です。 React routerはルーティング先をルーティング先のコンポーネントにのみ注入し、inでネストされたコンポーネントには注入しません。
this の質問に対する受け入れられた回答を参照してください。基本的な考え方は、ルーティングプロップを子コンポーネントに注入する方法を見つける必要があるということです。これを行うには、子をHOC withRouter
でラップします。
export default withRouter(connect(mapStateToProps, matchDispatchToProps)(ChildView));
これがお役に立てば幸いです。
WithRouterの使用は問題ありませんが、代わりのオプションは、親から子へ(withRouterを使用せずに)履歴を渡すことです。例えば:
親
<SignupForm history={this.props.history}/>
子
this.props.history.Push('/dashboard');
これは、ネストされたコンポーネントの問題です。
this.props.history.Push
は、ネストされたコンポーネントでは機能しません。
したがって、解決策はwithRouter
を使用することです。
withRouter
を使用するには、以下の2行の下に貼り付けます。
import { withRouter } from "react-router";
export default withRouter(connect(mapStateToProps, {
...
})(App));