调用browserHistory.push("/ url")后componentDidMount没有运行

cod*_*321 11 javascript reactjs react-router

我有一个问题,我会在登录后将用户发送到react-router路由,具体取决于以下内容:

        ...
        //check login
        browserHistory.push(self.props.destination_url);
Run Code Online (Sandbox Code Playgroud)

我期待着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)
} }/>
Run Code Online (Sandbox Code Playgroud)

此处组件在路由参数更改不起作用时不会重新装入.

这里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);
          });
    }
}
Run Code Online (Sandbox Code Playgroud)

在服务器/客户端上,您现在看到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;

...
Run Code Online (Sandbox Code Playgroud)

这将适用于学生的演示,但不是长期的.寻找一个只运行一次的生命周期方法,并且改变状态是安全的,不会导致无限循环

我的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",
Run Code Online (Sandbox Code Playgroud)

这些路线看起来像

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);
})
Run Code Online (Sandbox Code Playgroud)

小智 5

不要将 API 调用放在组件生命周期中。

创建一个动作

function getUserInfo(payload) {
  // do axios
  return { 
      type: 'GET_USER_INFO',
      payload: result_of_your_api_call,
      error: false/true
  };
}
Run Code Online (Sandbox Code Playgroud)

为这个动作创建减速器并改变减速器中的状态

之后,你需要 matStateToProps 和 mapDispatchToProps

connect(mapStateToProps, mapDispatchToProps)(YourMagicComponent)
Run Code Online (Sandbox Code Playgroud)

连接你的组件和你的 redux

之后,您将在组件中获得 redux 状态。有关更多信息,请阅读此http://redux.js.org/docs/basics/ExampleTodoList.html

记住 1. 组件初始化时,props 中除了 defaultProps 没有任何数据。2. componentDidMount 不知道组件外部的任何内容(仅可用默认道具和在组件安装之前定义的道具) 3. 如果您需要在 componentWillUpdate 中执行某些操作,您需要定义更新该组件的规则

componentWillUpdate(nextProps) {
  this.setState(key: nextProps.key)
}

shouldComponentUpdate(nextProps, nextState) {
  // fix for your update
  if (this.state.key !== nextProps.key) {
     return true;
  }
}
Run Code Online (Sandbox Code Playgroud)