草庐IT

javascript - 调用 browserHistory.push ("/url"后 componentDidMount 未运行)

coder 2024-05-14 原文

我有一个问题,我会在登录后将用户发送到 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/显示“挂载”、“卸载”、“状态更改”或“ Prop 更改”。我没有看到任何这些适用于此。是否有一个生命周期方法会在这个 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);
})

最佳答案

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

创建一个 Action

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

为此操作创建 reducer 并在 reducer 中改变状态

之后,你需要matStateToProps和mapDispatchToProps

connect(mapStateToProps, mapDispatchToProps)(YourMagicComponent)

连接你的组件和你的 redux

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

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

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

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

关于javascript - 调用 browserHistory.push ("/url"后 componentDidMount 未运行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46459787/

有关javascript - 调用 browserHistory.push ("/url"后 componentDidMount 未运行)的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  5. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  6. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  7. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  8. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  9. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  10. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

随机推荐