当前位置: 首页 > 知识库问答 >
问题:

构造函数被调用两次反应组件

艾泰
2023-03-14

我的react组件的构造函数被调用了两次,但我不知道为什么。我正在使用react redux存储我的应用程序的语言。我有一个基于浏览器语言设置默认语言的函数。LoginPage是第一个获得render的组件,因此我在其构造函数中调用了我的函数。基本上,它所做的就是比较并分派一个动作。当我用redux开发工具检查我的状态时,我看到它被调度了两次。我在构造函数中打印了虚拟数据,它也打印了两次。

登录页面。js

import React from 'react';
import {connect} from 'react-redux';
import {startLogin} from '../actions/auth';
import {setLanguage} from '../actions/lang';

export class LoginPage extends React.Component{

  constructor(props){
    super(props);
    this.setDefaultLanguage();
    console.log('i am constructor');
  }

  changeLanguage = (e) => {
    const lan = e.target.value;
    this.props.setLanguage(lan);
  };

  setDefaultLanguage = () => {
    const defaultLanguage = navigator.language || navigator.userLanguage || 'en-US';

    if(defaultLanguage == 'es'){
      this.props.setLanguage(defaultLanguage);
    }else{
      this.props.setLanguage('en');
    }
  }

  render(){
    return(
      <div className="box-layout">
        <div className="box-layout__box">
          <h1 className="box-layout__title">Expensify</h1>
          <p>It\'s time to get your expenses under control.</p>
          <button className="button" onClick={this.props.startLogin}>Log in with google</button>
          <select className="select" onChange={this.changeLanguage}>
            <option value="en">English</option>
            <option value="es">Español</option>
          </select>
        </div>
      </div>
    )
  };
}

const mapDispatchToProps = (dispatch) => ({
  startLogin: () => dispatch(startLogin()),
  setLanguage: (language) => dispatch(setLanguage(language))
});

export default connect(undefined, mapDispatchToProps)( LoginPage);

一个pp.js

import React from 'react';
import ReactDom from 'react-dom';
import {Router, Route, Switch} from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import ExpenseDashBoardPage from '../components/ExpenseDashBoardPage';
import AddExpensePage from '../components/AddExpensePage';
import EditExpensePage from '../components/EditExpensePage';
import NotFoundPage from '../components/NotFoundPage';
import LoginPage from '../components/LoginPage';
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';

export const history = createHistory();

const AppRouter = () => (
  <Router history={history}>
    <div>
      <Switch>
        <PublicRoute path="/" component={LoginPage} exact={true} />
        <PrivateRoute path="/dashboard" component={ExpenseDashBoardPage} />
        <PrivateRoute path="/create" component={AddExpensePage} />
        <PrivateRoute path="/edit/:id" component={EditExpensePage} />
        <Route component={NotFoundPage} />
      </Switch>
    </div>

  </Router>
)

export default AppRouter;

共有3个答案

桂志新
2023-03-14

是的。这是有意的,并记录在这里。它只发生在开发模式中。

https://reactjs.org/docs/strict-mode.html#detecting-意外副作用

麻超
2023-03-14

我遇到了同样的问题,因为我在我的公共路由中重定向用户。因此,它对组件进行了两次渲染。如果您正在使用

history.push('/');

这将渲染组件两次。

冯育
2023-03-14

首先,您不应该从构造函数中调用Redux操作或任何类型的AJAX。这些事情应该在componentDidMount()中完成。

第二,作为道具的一部分,我会要求商店提供语言。如果未定义,则在componentDidMount()中调用您的setDefaultLanguage()

我至少会做到以下几点:

export class LoginPage extends React.Component {
  componentDidMount() {
    if (!this.props.lang) {
        this.setDefaultLanguage();
    }
  }

  changeLanguage = (e) => {
    const lan = e.target.value;
    this.props.setLanguage(lan);
  };

  setDefaultLanguage = () => {
    const defaultLanguage = navigator.language || navigator.userLanguage || 'en-US';

    if(defaultLanguage == 'es'){
      this.props.setLanguage(defaultLanguage);
    }else{
      this.props.setLanguage('en');
    }
  }

  render() {
    return(
      <div className="box-layout">
        <div className="box-layout__box">
          <h1 className="box-layout__title">Expensify</h1>
          <p>It\'s time to get your expenses under control.</p>
          <button className="button" onClick={this.props.startLogin}>Log in with google</button>
          <select className="select" onChange={this.changeLanguage}>
            <option value="en">English</option>
            <option value="es">Español</option>
          </select>
        </div>
      </div>
    )
  };
}

const mapStateToProps = state => ({
    // Assuming `steate.lang` is where you would set the language.
    lang: state.lang
});

const mapDispatchToProps = (dispatch) => ({
  startLogin: () => dispatch(startLogin()),
  setLanguage: (language) => dispatch(setLanguage(language))
});

const mergeProps = (stateProps, dispatchProps) => ({ ...stateProps, ...dispatchProps });

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(LoginPage);
 类似资料:
  • 我有一个帖子列表,我试图在构造函数或componentDidMount中为每个帖子调用一个操作。但不知何故,当我发送一个新消息时,构造函数和componentDidMount函数会被调用两次。 当从列表中读取帖子时,这些函数仅被调用一次。但是当我发送一条新消息时,他们会被呼叫两次。 我怎样才能避免这种情况。我试着像这样使用ComponendDupDate函数:

  • 我是新的反应,我试图用它开发一个简单的网络应用程序,但我得到了一个错误。当我加载一个类组件时,我的构造函数被调用两次,你能帮忙吗? 原木地被击中两次。在一些组件中,我希望进行一个命中DB的API调用,但我只想命中它一次。在许多情况下,使用并不方便,因为道具只出现在之后,因此我想在中调用(我不会使用setState,这会导致重新加载render)。 提前感谢

  • 正如我的类名所暗示的那样:如果我的类是迭代器的实例,我想测试一下。因此,我想知道,如果它只需要实现接口就可以这样做,似乎就足够了。 然而,当我通过JUNIT Test运行以下类时,我得到了以下控制台输出: 似乎类构造函数被调用了两次!但是我不知道第二次调用来自哪里。我已经测试了“if”参数的变体以排除有故障,例如 然而,它在所有3种情况下都被调用了。因此,我假设Unit Test首先尝试,需要为自

  • 问题内容: 我的Spring应用程序有一个问题,该应用程序启动时会两次创建我的@Service类。我知道这是我的配置存在的问题,就像我以前经历过的那样,但是我到底在做什么错呢? 我在下面布置配置的方式有什么根本错误吗?(我忽略了我认为无关的所有内容) web.xml: myapp-servlet.xml myapp-config.xml 问题答案: 除了@GaryF的答案外,还有以下针对该问题的漂

  • 问题内容: 在以下示例中,当单击时,将显示而不是。为什么?您将如何解决? 问题答案: React的对帐算法假定没有相反的信息,如果自定义组件出现在后续渲染的同一位置,则它与以前的组件相同,因此将重用前一个实例,而不是创建一个新实例。 如果要实现,则会看到被调用。 不同的节点类型 元素不太可能生成看起来像a 会生成的DOM 。无需花费时间尝试匹配这两种结构,React只是从头开始重建树。 作为推论,

  • 问题内容: 构造函数何时被调用? 创建对象之前。 在对象创建期间。 创建对象之后。 问题答案: 分配对象内存,初始化具有初始值的字段变量,然后调用构造函数,但是其代码在对象超类的构造函数代码之后执行。