构造函数两次调用React Component [英] Constructor getting called twice 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屋!