this.props.history.Push(..)
を使用してプログラムでルーティングしようとしていますが、うまくいかないようです。
ルーターは次のとおりです。
import {
BrowserRouter as Router,
Route
} from 'react-router-dom';
<Router>
<Route path="/customers/" exact component={CustomersList} />
<Route path="/customers/:id" exact component="{Customer} />
</Router>
CustomerListでは、顧客のリストが表示されます。顧客(li)をクリックすると、アプリケーションが顧客にルーティングされます。
import { withRouter } from 'react-router'
class Customers extends Component {
static propTypes = {
history: PropTypes.object.isRequired
}
handleCustomerClick(customer) {
this.props.history.Push(`/customers/${customer.id}`);
}
render() {
return(
<ul>
{ this.props.customers.map((c) =>
<li onClick={() => this.handleCustomerClick(c)} key={c.id}>
{c.name}
</li>
</ul>
)
}
}
//connect to redux to get customers
CustomersList = withRouter(CustomersList);
export default CustomersList;
コードは部分的ですが、状況を完全に示しています。ブラウザーのアドレスバーはhistory.Push(..)に応じて変化しますが、ビューは更新されず、Customerコンポーネントはレンダリングされず、CustomersListはまだ存在しています。何か案は?
だから私は答えを期待してこの質問に来ましたが、役に立ちませんでした。利用した
const { history } = this.props;
history.Push("/thePath")
同じプロジェクトで、期待どおりに機能しました。さらに実験を重ねて比較対照すると、このコードがネストされたコンポーネント内で呼び出されると実行されないことに気付きました。そのため、レンダリングされたページコンポーネントのみがこの関数を呼び出して、適切に機能します。
ワーキングサンドボックスの検索 こちら
リアクションルーターの最新バージョンでは、状況が少し変わっているようです。これで、コンテキストを介して履歴にアクセスできます。 this.context.history.Push('/path')
このgithubの問題への返信も参照してください。 https://github.com/ReactTraining/react-router/issues/4059
子コンポーネントに履歴をロードしようとすることができます。そのためには、小道具に「歴史」を渡します。そんな感じ:
return (
<div>
<Login history={this.props.history} />
<br/>
<Register/>
</div>
)
私(react-router v4、react v16)の問題は、ナビゲーションコンポーネントが大丈夫だったことです:
import { Link, withRouter } from 'react-router-dom'
class MainMenu extends Component {
render() {
return (
...
<NavLink to="/contact">Contact</NavLink>
...
);
}
}
export default withRouter(MainMenu);
どちらかを使用して
to="/contact"
または
OnClick={() => this.props.history.Push('/contact')};
動作は同じままでした-ブラウザのURLは変更されましたが、間違ったコンポーネントがレンダリングされ、同じ古いURLでルーターが呼び出されました。
原因はルーター定義にあります。 MainMenuコンポーネントをRouterコンポーネントの子として移動する必要がありました!
// wrong placement of the component that calls the router
<MainMenu history={this.props.history} />
<Router>
<div>
// this is the right place for the component!
<MainMenu history={this.props.history} />
<Route path="/" exact component={MainPage} />
<Route path="/contact/" component={MainPage} />
</div>
</Router>
古い質問のようですが、それでも関連性があります。
blocked update の問題だと思います。
主な問題は、現在のURL(現在のURL)と同じコンポーネント(Costumers
)によって新しいURL(ルート)がレンダリングされることになっていることです。
そのため、解決策はかなり単純で、ウィンドウのURLを小道具として作成します。したがって、reactは小道具の変更(したがってURLの変更)を検出し、それに応じて動作する可能性があります。
推奨:完全に制御されていないキー付きコンポーネント と呼ばれる公式の反応ブログで説明されているニースのユースケース。
解決策は、render() { return( <ul>
から変更することです
render() { return( <ul key={this.props.location.pathname}>
へ
そのため、react-routerによって場所が変更されるたびに、コンポーネントは(reactによって)破棄され、新しいコンポーネントは正しい値(reactによって)で開始されます。
ああ、location
をpropとしてコンポーネント(Costumers
)に渡します。まだ渡されていない場合、リダイレクトが発生します。
それが誰かを助けることを願っています。
CustomersListではなくCustomersコンポーネントをエクスポートする必要があります。
CustomersList = withRouter(Customers);
export default CustomersList;
ルーターでは使用しないでください。
handleSubmit(e){
e.preventDefault();
this.props.form.validateFieldsAndScroll((err,values)=>{
if(!err){
this.setState({
visible:false
});
this.props.form.resetFields();
console.log(values.username);
const path = '/list/';
this.props.history.Push(path);
}
})
}
うまくいきます。