构造函数两次调用React Component [英] Constructor getting called twice React Component

查看:73
本文介绍了构造函数两次调用React Component的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The constructor of my react component is getting called twice but I can't figure out why. I am using react-redux to store the language of my app. I have a function that set the default language base on browser's language. LoginPage is the first component that gets render so I called my function in its constructor. Basically what it does is compare and dispatch an action. When I checked my state with redux developer tools I saw that it was getting dispatched twice. I printed dummy data in the constructor and it gets printed twice too.

LoginPage.js

LoginPage.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);

App.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;


推荐答案

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

First of all, you should not call Redux actions or any kind of AJAX from within the constructor. Those things should be done in componentDidMount().

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

Second, I would request the language from the store as part of props. If not defined, then in componentDidMount() call your 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);

这篇关于构造函数两次调用React Component的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆