【发布时间】:2018-03-09 15:28:42
【问题描述】:
我有一个问题,我将在登录后将用户发送到 react-router 路由,基于以下几点:
...
//check login
browserHistory.push(self.props.destination_url);
我期待 componentDidMount 运行,因为自从我加载应用程序后,该组件就没有出现在屏幕上,但它不会。如果我在导航栏中单击指向它的链接(react-router 链接),componentDidMount 会运行。
由于browserHistory.push(self.props.destination_url); 路由更改,当此组件出现在屏幕上时,我只需要进行 API 调用。我尝试过类似
<Router createElement={ (component, props) =>
{
const { location } = props
const key = `${location.pathname}${location.search}`
props = { ...props, key }
return React.createElement(component, props)
} }/>
这里是Component does not remount when route parameters change,但它不起作用。
这里http://busypeoples.github.io/post/react-component-lifecycle/ 显示“on mount”、“on unmount”、“on state change”或“on props changes”。我没有看到任何这些适用于此。在此 browserHistory 推送转换之后是否有生命周期方法将运行?
我一直在尝试随机生命周期方法,componentWillUpdate 确实在browserHistory.push 之后运行,但它运行了数百次,完全减慢了应用程序的速度。我假设我在其中所做的某些事情导致了几乎无限的循环:
componentWillUpdate() {
console.log('it ran componentWillUpdate');
if (this.props.email) {
console.log('firing off /api/userInfo');
let self = this;
axios.post('/api/userInfo', {email: this.props.email})
.then(function (response) {
let result = response.data.result;
console.log('after calling /api/userInfo');
console.log(response);
console.log(result);
if (result) {
self.setState({restaurant_profile: result});
}
})
.catch(function (error) {
console.log("Something went wrong trying to check for a user's restaurant profile");
console.log(error);
});
}
}
在服务器/客户端上,您现在可以看到 POST 运行了数百次:
Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = 'fake@fake.com' LIMIT 1;
Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = 'fake@fake.com' LIMIT 1;
Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = 'fake@fake.com' LIMIT 1;
Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = 'fake@fake.com' LIMIT 1;
...
这适用于学生的演示,但不能长期使用。寻找一种只运行一次的生命周期方法,并且改变状态是安全的,不会导致无限循环
我的 r 依赖项看起来像
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.6",
"react-router": "^3.0.5",
"react-router-dom": "^4.2.2",
"react-transform-hmr": "^1.0.4",
"redux": "^3.7.2",
这些路线看起来像
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import { Router, Route, Link, IndexRoute, browserHistory } from "react-router";
import reducers from "./reducers";
import { loadConfig, getConfig } from "./config";
import Nav from "./Nav";
import LoginPage from "./containers/LoginPage";
import MapShowRestaurants from "./components/MapShowRestaurants";
import RestaurantRegistration from "./containers/RestaurantRegistration";
const createStoreWithMiddleware = applyMiddleware()(createStore);
getConfig.then((config) => {
loadConfig(config);
ReactDOM.render(
(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory}>
<Route path="/" component={Nav}>
<IndexRoute component={MapShowRestaurants} />
<Route path="/login" component={LoginPage} />
<Route path="/registerRestaurant" component={RestaurantRegistration} />
</Route>
</Router>
</Provider>
), document.querySelector('.container'));
})
.catch((err) => {
console.log(err);
})
【问题讨论】:
-
我知道 componentDidMount 只被调用一次,这就是为什么它不能像你期望的那样工作(因为(我相信)react-router 在实际调用之前会进行初始渲染)我可能是错的 - 因此评论而不是答案。我会看看我是否找不到相关的文档。此外,正如您所发现的,componentWillUpdate() 也不适合这样做……您可以尝试创建自己的方法,然后在 browserPush 回调中调用它?只是一个想法。
-
在
browserHistory.push中如何称呼它?据我了解,您只需将要访问的 URL 传递给它,它会将其推送到历史记录中并重新路由您到那里 -
我认为您可以添加回调...在查找该信息时,我发现:github.com/ReactTraining/react-router/issues/3554
-
@codyc4321 你能为我们提供两件事吗?首先,重要的是,您使用的是哪个版本的反应路由器,其次,您定义的路由。谢谢
-
@codyc4321 你确定没有调用“componentDidMount”吗?我试图在这个沙箱中尽可能地复制您的场景:codesandbox.io/s/ov84yrzyy5 它按我的预期工作,
componentDidMount每次我“导航”到该组件时都会被调用,当我我已经在那个组件上了。
标签: javascript reactjs react-router