Javascript 在 componentDidMount() 之前调用 React render()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45337165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React render() is being called before componentDidMount()
提问by user3574492
In my componentDidMount()I am making an API call to fetch some data, this call then sets a state object that I use in my render.
在我componentDidMount()的 API 调用中,我调用了一些数据,然后这个调用设置了一个我在渲染中使用的状态对象。
componentDidMount() {
const { actions } = this.props;
this.increase = this.increase.bind(this);
// api call from the saga
actions.surveyAnswersRequest();
// set breadcrumb
actions.setBreadcrumb([{ title: 'Score' }]);
actions.setTitle('Score');
this.increase();
}
In my render function I pass some prop values onto the view file:
在我的渲染函数中,我将一些 prop 值传递给视图文件:
render() {
const { global, gallery, survey_answers, survey, survey_actual_answers } = this.props;
if (global.isFetching) {
return <Loading />;
}
return this.view({ gallery, survey_answers, survey, survey_actual_answers });
}
The problem I am having is that the survey_actual_answersprop is not being set the first time that the page is loaded, however when I refresh the page the prop returns the data fine and the rest of the script will run. It's only the first time that it returns an empty array for that prop value.
我遇到的问题是survey_actual_answers在第一次加载页面时没有设置 prop,但是当我刷新页面时,prop 返回的数据很好,脚本的其余部分将运行。这只是第一次为该 prop 值返回一个空数组。
This is how I have passed my props in:
这是我传递道具的方式:
Score.propTypes = {
actions: PropTypes.object.isRequired,
global: PropTypes.object.isRequired,
survey: PropTypes.object.isRequired,
survey_answers: PropTypes.object.isRequired,
gallery: PropTypes.object.isRequired,
survey_actual_answers: PropTypes.array.isRequired,
survey_score_system: PropTypes.array.isRequired,
survey_styles: PropTypes.object.isRequired,
survey_general_doc_data: PropTypes.object.isRequired
};
function mapStateToProps(state, ownProps) {
return {
...ownProps,
global: state.global,
gallery: state.gallery,
survey: state.survey,
survey_actual_answers: state.survey.survey_actual_answers,
survey_answers: state.survey.survey_answers,
survey_score_system: state.survey.survey_score_system,
survey_styles: state.survey.survey_styles,
survey_general_doc_data: state.survey.survey_general_doc_data,
isFetching: state.isFetching
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
...globalActions,
...galleryActions,
...surveyActions
}, dispatch)
};
}
Does anyone know why this is happening? It's almost as if it's not calling componentDidMount at all.
有谁知道为什么会这样?就好像它根本没有调用 componentDidMount 一样。
回答by EJ Mason
This is happening because of how React works fundamentally. React is supposed to feel fast, fluent and snappy; the application should never get clogged up with http requests or asynchronous code. The answer is to use the lifecycle methods to control the DOM.
这是因为 React 的工作原理。React 应该让人感觉快速、流畅和活泼;应用程序永远不应该被 http 请求或异步代码阻塞。答案是使用生命周期方法来控制 DOM。
What does it mean when a component mounts?
组件挂载是什么意思?
It might be helpful to understand some of the React vocabularies a little better. When a component is mounted it is being inserted into the DOM. This is when a constructor is called. componentWillMount is pretty much synonymous with a constructor and is invoked around the same time. componentDidMount will only be called once after the first render.
更好地理解一些 React 词汇可能会有所帮助。当一个组件被挂载时,它被插入到 DOM 中。这是调用构造函数的时候。componentWillMount 几乎是构造函数的同义词,并且大约在同一时间被调用。componentDidMount 只会在第一次渲染后被调用一次。
componentWillMount--> render--> componentDidMount
componentWillMount-->渲染--> componentDidMount
How is that different than rerendering or updating?
这与重新渲染或更新有何不同?
Now that the component is in the DOM, you want to change the data that is displayed. When calling setState or passing down new props from the parent component a component update will occur.
现在组件位于 DOM 中,您想要更改显示的数据。当调用 setState 或从父组件传递新的 props 时,将发生组件更新。
componentWillRecieveProps--> shouldComponentUpdate-->componentWillUpdate
-->render-->componentDidUpdate
componentWillRecieveProps--> shouldComponentUpdate--> componentWillUpdate
-->渲染--> componentDidUpdate
It is also good to note that http requests are usually done in componentDidMount and componentDidUpdate since these are places that we can trigger a rerender with setState.
还需要注意的是,http 请求通常在 componentDidMount 和 componentDidUpdate 中完成,因为这些是我们可以使用 setState 触发重新渲染的地方。
So how do I get the data before the render occurs?
那么如何在渲染发生之前获取数据呢?
Well, there are a couple of ways that people take care of this. The first one would be to set an initial state in your component that will ensure that if the data from the http request has not arrived yet, it will not break your application. It will use a default or empty state until the http request has finished.
嗯,人们有几种方法可以解决这个问题。第一个是在您的组件中设置一个初始状态,以确保如果来自 http 请求的数据尚未到达,它不会破坏您的应用程序。它将使用默认或空状态,直到 http 请求完成。
I usually don't like to have a loading modal, but sometimes it is necessary. For instance, when a user logs in you don't want to take them to a protected area of your site until they are finished authenticating. What I try to do is use that loading modal when a user logs in to front load as much data as I possibly can without affecting the user experience.
我通常不喜欢有一个加载模式,但有时它是必要的。例如,当用户登录时,在他们完成身份验证之前,您不希望将他们带到站点的受保护区域。我尝试做的是在用户登录到前端时使用该加载模式,在不影响用户体验的情况下加载尽可能多的数据。
You can also make a component appear as loading while not affecting the user experience on the rest of the site. One of my favorite examples is the Airbnb website. Notice that the majority of the site can be used, you can scroll, click links, but the area under 'experiences' is in a loading state. This is the correct way to use React and is the reason why setState and HTTP requests are done in componentDidMount/componentDidUpdate.
您还可以使组件显示为正在加载,同时不影响站点其余部分的用户体验。我最喜欢的例子之一是Airbnb 网站。请注意,该站点的大部分内容都可以使用,可以滚动,单击链接,但是“体验”下的区域处于加载状态。这是使用 React 的正确方法,也是 setState 和 HTTP 请求在 componentDidMount/componentDidUpdate 中完成的原因。
回答by truong luu
Using setState in componentdidmount. This my code:
在 componentdidmount 中使用 setState。这是我的代码:
async componentDidMount() {
danhSachMon = await this.getDanhSachMon();
danhSachMon=JSON.parse(danhSachMon);
this.setState(danhSachMon);
}
render() {
return (
<View>
<FlatList
data={danhSachMon}
showsVerticalScrollIndicator={false}
renderItem={({ item }) =>
<View >
<Text>{item.title}</Text>
</View>
}
keyExtractor={(item, index) => index.toString()}
/>
</View>
)
}
回答by EduLopez
componentWillMount is deprecated. Now you need to use "DidMount" and as soon as it finishes and changes the DOM on render, react will handle everything else.
不推荐使用 componentWillMount。现在您需要使用“DidMount”,一旦它完成并在渲染时更改 DOM,react 将处理其他所有事情。
Make sure you update and use the correct variables/state/props in the render.
确保在渲染中更新并使用正确的变量/状态/道具。
componentDidMount() {
const { applicationId } = this.props;
if (applicationId) {
ApplicationService.getQuotesByApplicationId(applicationId).then((response) => {
const quotes = _.get(response, 'data.data');
this.setState({
quotes,
});
});
....
}
render() {
const quotes = _.get(this.state, 'quotes', null);
return (
<div className="application">
<h4 className="application__sub">Application</h4>
<h1 className="application__title">Quote Comparison</h1>
<div className="form-wrapper">
{this.renderQuotes(quotes)}
</div>
<div />
</div>
);
}
Here I get the quotes from the API and as soon as it finishes it set a variable in the state, then the render and react do their work.
在这里,我从 API 获取引号,一旦它完成,它就会在状态中设置一个变量,然后渲染和反应就会开始工作。

