react中 reactpurecomponenttWillMount,reactpurecomponenttDidMount有什么用处

老师您好,我有一个关于react生命周期中关于componentDidMount事件的问题
老师您好,具体问题是这样的:我在componentDidMount中加了一个alert,在pc浏览器上是先显示界面元素,然后显示alert弹出框;但是在移动浏览器上是先显示alert,在显示界面元素.请问一下componentDidMount事件的具体意思是什么???困扰了我好久,希望老师帮忙解答一下,谢谢老师啦以下是界面截图:第一张是pc谷歌浏览器;第二张是安卓uc浏览器(我在winform和ipad的safri都是这样的效果)
写下你的评论...
Copyright (C)
All Rights Reserved | 京ICP备 号-2【第902期】React 的生命周期的使用场景
在4月8号React今日发布了15.5.0版本。今日早读文章由@JohannLai授权分享。
正文从这开始~
上名这个图片,就是 React 组件的生命周期,从形成 (pre-mounting)到销毁 (unmounting) 的过程。
React 的优雅之处就在于,它把复杂的 UI 分解成很小的部分。 我们不仅仅可以划分我们的应用,而且我们还可以定制我们每一个组件。
通过组件的生命周期方法,我们可以控制当UI的每个微小部分渲染,更新,考虑重新渲染,然后完全消失时会发生什么事情。
componentWillMount
您的组件将很快就会出现在屏幕上面。这个大块的渲染功能与其所有精美的 JSX 一样,即将被调用。那你想做什么?
答案是… 可能不是很多。 但是 componentWillMount 的确用处不会太大。
关于 componentWillMount 的事情是,没有组件可以玩,所以你不能做任何涉及DOM的事情。(译者:因为还没渲染组件)
此外,自从您的组件的构造函数( constructor )被调用以来,没有任何变化,但是,无论如何,您应该在其中设置组件的默认配置。
exportdefaultcalss Sidebar extendsComponent{
constructor(props){
super(props)
this.state ={
analyticsOpen:false,
requirementsOpen:false,
barndInfoOpen:false
现在您的组件处于默认位置,几乎所有的东西都应该由其余的组件代码来处理,而不需要额外的生命周期方法。
例外是只能在运行时完成的任何设置,说白了也就是连接到外部 API 。举个栗子,如果您的应用程序使用Firebase,则需要在应用程序首次挂载(mounting)时进行设置。
但关键是,这样的配置应该在应用程序的最高级别组件(根组件)。 这意味着99%的组件应该不能使用 componentWillMount 。
您可能会看到使用componentWillMount的人启动AJAX调用来加载组件的数据。 千万不要这样做,我们马上就会聊到这个。
接下来,更有用的方法是:
最常见的用例: 您的根组件中的应用程序配置。
可以调用setState:不要。改用默认状态( default state )。
componentDidMount
现在我们在说话您的组件在那里,挂载了并准备好使用了。怎么办?
这里是您加载数据的位置。我会让 Tyler McGinnis 解释为什么:
您不能保证在组件挂载之前,AJAX请求将 resolve 。如果这样做,那意味着你会尝试在一个未挂载的组件上设置StState,这不仅不会起作用,反而 React 会对你大喊大叫。在componentDidMount中执行AJAX将保证有一个要更新的组件。
ComponentDidMount 也可以在做很多你在没有组件的时候不能做的事情。 下面举几个栗子:
绘制您刚刚渲染的
从元素集合初始化 masonry 网格布局
增加事件监听器
基本上,你可以在这里做任何刚刚因为没有 DOM 而不能做的设置,并且可以获取你所需要的全部数据。
最常见的用例: 启动AJAX调用,以加载组件的数据。
可以调用setState:是的。
componentWillReceiveProps
我们的组成部分做得很好,突然之间,一大堆新的 props 到达了,使到组件处于混乱状态。
很有可能一些由父组件的componentDidMount加载的数据终于到达,并被传递下来。
在我们的组件对新的 props 进行任何操作之前,将调用componentWillReceiveProps,并将下一props 作为参数。
现在,我们正在处于一个很有趣的地方,我们可以访问下一个 props (通过nextProps)和我们当前的 props (通过this.props)。
下面这些是我们在componentWillReceiveProps 中需要做的:
检查哪些props 会改变(使用componentWillReceiveProps的大警告 - 有时它什么也没有改变时被调用; React 只是想做一个检查)
如果props 会以重要的方式改变props,就行事。
下面是一个例子。假设我们在上面提到,我们有一个
当我们收到新的props ,如果百分比发生变化,我们想重新绘制网格。以下是代码:
componentWillReceiveProps(nextProp ){
if(this.props.percent !==nextProps.percent){
this.setUpCirCle(nextProps.percent)
注意:在初始渲染时不调用 componentWillReceiveProps 。
我的意思是在技术上,组件正在接收props,但没有任何旧的props要比较,所以…不算。
最常见的用例:根据特定的props,更改来触发状态(state)转换。
是否可以调用setState: Yes
shouldComponentUpdate
现在我们的组件越来越紧张了。
我们有新的props。典型的React教条说,当一个组件接收到新的props或新的state时,它应该更新。
但是我们的组件有点焦虑,首先要求许可。
这是我们所需要的 —— shouldComponentUpdate方法,以 nextProps 为第一个参数,nextState是第二个参数:
shouldComponentUpdate(nextProps,nextState){
returnthis.props.engagement !==nextProps,engagement
||nextState.input !==this.state.input
shouldComponentUpdate应该总是返回一个布尔值 —— 就像这个问题的答案
–& “我可以渲染吗?”
–& 是的,小组件,你可以去渲染。
默认情况下它总是返回true。
但是,如果您担心浪费渲染
其实,shouldComponentUpdate是提高性能的好地方。
我以这种方式写了一篇关于使用shouldComponentUpdate的文章 - 看看:
How to Benchmark React Components: The Quick and Dirty Guide
在这篇文章中,我们谈论一个有很多fields的表格。问题是,当表重新渲染时,每个字段也将重新渲染,速度很慢,效率很低。
ShouldComponentUpdate允许我们说:只有当所关心的props的改变的时候才更新!
但请记住,如果您设置并忘记它可能会导致重大问题,因为您的React组件将无法正常更新。所以谨慎使用。
最常见的用例: 当您的组件 re-render (重新渲染)时,完全控制。
是否可以调用setState: No
componentWillUpdate
哇,什么过程现在我们承诺更新。”希望我在重新渲染之前先做任何事情?” 我们的组件问。不,我们说。停止打扰我们。在整个MuseFind代码库中,我们从不使用componentWillUpdate。在功能上,它基本上与componentWillReceiveProps相同,除非你不允许调用this.setState。
如果您正在使用shouldComponentUpdate 并且需要在props更改时执行某些操作,那么componentWillUpdate就会很有意义。
最常见的用例: 在一个也有shouldComponentUpdate(但不能访问以前的props)的组件上使用而不是componentWillReceiveProps。
是否可以调用setState: No
componentDidUpdate
很棒!小组件!
在这里我们可以和componentDidMount做同样的事情 : 重新设置我们的 masonry 布局,重绘我们的canvas, 等。
等等 - 我们没有在componentWillReceiveProps中重画我们的canvas 吗?
是的我们没有做。原因是:在componentDidUpdate中,你不知道为什么它更新。
因此,如果我们的组件接收到的canvas数量超过了与我们的canvas相关的props,我们不希望每次更新时都会浪费时间重绘canvas 上面。
这并不意味着componentDidUpdate没有用。要回到我们的 masonry 布局示例,我们要在DOM自身更新后重新排列网格,所以我们使用componentDidUpdate 来完成。
componentDidUpdate(){
this.createGrid()
最常见的用例:更新DOM以响应prop或state更改。
是否可以调用setState: Yes
componentWillUnmount
几乎结束了~
你的组件将会消失。也许永远,这很伤心。
在它之前,它询问你是否有任何最后的请求。
在这里,您可以取消任何传出的网络请求,或删除与组件关联的所有事件监听器。
基本上,清理任何只涉及到有关的组件的哦事情,
当它走了,它应该完全消失。
componentWillUnmount(){
window.removeEventListen('resize',this,resizeListener)
最常见的用例:清理组件中残留的残留物。
是否可以调用setState: No
在理想的世界中,我们不会使用生命周期方法。我们所有的渲染问题都将通过state 和 prop进行控制。
但它事实上并不是一个理想的世界,有时您需要更准确地控制组件更新的方式和时间。
谨慎使用这些方法,并小心使用。我希望这篇文章有助于阐明什么时候和如何使用生命周期方法。
最后,为你推荐:
译者:@JohannLai
译文://React Lifecycle Methods/
作者:@MuseFind
原文:/react-lifecycle-methods-how-and-when-to-use-them-b1
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
var Diver = React.createClass({
getInitialState:function(){
return (styles = {
width:'100%',
height:'100%',
background:'red',
position:'fixed'
componentWillMount:function(){
alert('ok')
render:function(){
&div className = 'container' style={this.state}&{this.props}&/div&
componentDidMount:function(){
alert('OK')
React.render(
&Diver name = 'myname'/&,
document.querySelector('.wrap')
componentWillMount与componentDidMount这两个函数的作用是什么?还望大家赐教
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
官方文档有详细说明,两者主要区别是调用顺序,一个在render之前,一个在render之后。另外,官方建议是,用constructor()替换componentWillMount
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
根据文档说法,从后台获取数据一定要放在componentDidMount里面调用,为什么不能在constructor或者componentWillMount里面调用?有什么不同?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
这与React组件的生命周期有关,组件挂载时有关的生命周期有以下几个:
constructor()
componentWillMount()
componentDidMount()
上面这些方法的调用是有次序的,由上而下,也就是当说如果你要获取外部数据并加载到组件上,只能在组件"已经"挂载到真实的网页上才能作这事情,其它情况你是加载不到组件的。
componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
constructor被调用是在组件准备要挂载的最一开始,所以此时组件尚未挂载到网页上。
componentWillMount方法的调用在constructor之后,在render之前,在这方法里的代码调用setState方法不会触发重渲染,所以它一般不会用来作加载数据之用,它也很少被使用到。
一般的从后台(服务器)获取的数据,都会与组件上要用的数据加载有关,所以都在componentDidMount方法里面作。虽然与组件上的数据无关的加载,也可以在constructor里作,但constructor是作组件state初绐化工作,并不是设计来作加载数据这工作的,所以所有有副作用的代码都会集中在componentDidMount方法里。
补充一下,Redux作初始数据载入时,是可以不需透过React组件的生命周期方法,大致的方式如下代码:
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './App'
// reducer
function items(state = [], action) {
switch (action.type) {
case 'LOAD_ITEMS':
return [...action.payload]
return state
// 创建store
const store = createStore(items)
fetch('http://localhost:8888/items', {
method: 'GET'
.then((response) =& {
// ok代表状态码在200-299
if (!response.ok) throw new Error(response.statusText)
return response.json()
.then((itemList) =& {
// 作dispatch动作,载入外部数据完成之后
store.dispatch({ type: 'LOAD_ITEMS', payload: itemList })
.catch((error) =& { throw new Error(error.message) })
// React组件加载到真实DOM上
ReactDOM.render(
&Provider store={store}&
&/Provider&, document.getElementById('root'))
为何可以这样作的原因,是Redux的store中的状态有一个最初始的值(reducer上传参里的默认值),组件先初始化完成,接著异步的fetch用promise语法,在作完外部数据加载后,发送动作出来,此时reducer更动store里的状态,react-redux绑定器会触发React组件的重渲染,所以组件上数据会自动更新。
有问题再问吧,代码写得简略但测试过是可执行的。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
constructor()中获取数据的话,如果时间太长,或者出错,组件就渲染不出来,你整个页面都没法渲染了。componentDidMount()中能保证你的组件已经正确渲染。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
1、通常我在componentWillMount发送ajax(渲染dom之前做的操作)
2、componentDidMount也可以做ajax操作(渲染dom完成之后做的操作)
那么,这2种情况如何区分呢?
当你的render函数需要有数据才能渲染的时候,就在componentWillMount做操作。
render() {
return data && &div&{data}&/div&
当你的render不需要数据,先渲染dom结构,就在componentDidMount操作。
render() {
const { data } = this.props
&span&我要先渲染&/span&
&span&{data || ''}&/span&
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
你既然了解的周期的顺序,那就很好理解了啊!willMount在dom没有渲染前先进行的方法,如果这个时候请求ajax那么势必会有等待的这一刻,然后排队渲染dom,而didMount是在dom加载后在进行的方法,而这个时候请求ajax前面没有任何等待,直接请求,然后如果你setState那么整个虚拟dom会在此渲染,此时再将获得的数据进行渲染,这样就感觉很顺的就执行下去了。而再次渲染的同时大部分的dom都是没有改变的,只有部分改变,所以渲染的速度会很快
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
感谢各位的回答:总结一下不建议在constructor和componentWillMount里写的原因是
会阻碍组件的实例化,阻碍组件的渲染
如果用setState,在componentWillMount里面触发setState不会重新渲染
而在React Redux中,由于触发的渲染方式不同,是可以不需透过React组件的生命周期方法,所以我感觉可以在生命周期的任何地方调用。当然,在consttructor和componentWillMount还是会阻碍一点点组件的实例化和渲染。
由于@eyesofkids写的全面一点,我采纳他的了。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
因为有很多前置工作要做
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我一直想找到合理的答案,但是呢,这里说的感觉都不合理。1.获取数据肯定是以异步方式进行,不会阻碍组件渲染(只会耽误请求发送这个时间),然后接着渲染,等异步返回数据后,如果成功再进行setState操作,setState是将更新的状态放进了组件的__pendingStateQueue队列,react不会立即响应更新,会等到组件挂载完成后,统一的更新脏组件(需要更新的组件)。放在constructor或者componentWillMount里面反而会更加有效率。2.再说说React-Redux,要想让组件更新,必须要有用connect(...)(yourComponent)封装的容器(高阶)组件,这个组件会监听store变化,内部调用setState触发你的组件更新。数据处理都是通过dispatch(action)进行,自己并不会在组件的声明周期内直接ajax获取取数据。使用redux这个问题就成为了再组件声明周期的哪个节阶段dispatch(action)获取数据才合理?总结:我认为原因有:1.跟服务器端渲染(同构)有关系,如果在componentWillMount里面获取数据,fetch data会执行两次,一次在服务器端一次在客户端。在componentDidMount中可以解决这个问题。2.在componentWillMount中fetch data,数据一定在render后才能到达,如果你忘记了设置初始状态,用户体验不好。3.react16.0以后,componentWillMount可能会被执行多次。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我使用了redux,我觉得componentWillMount和componentDidMount都可以做异步处理,我比较喜欢在componentWillMount做处理,我们可以看看react16.0,貌似生命周期触发的次数有影响
该答案已被忽略,原因:
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
根据文档说法,从后台获取数据一定要放在componentDidMount里面调用,为什么不能在constructor或者componentWillMount里面调用?有什么不同?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
1、通常我在componentWillMount发送ajax(渲染dom之前做的操作)
2、componentDidMount也可以做ajax操作(渲染dom完成之后做的操作)
那么,这2种情况如何区分呢?
当你的render函数需要有数据才能渲染的时候,就在componentWillMount做操作。
render() {
return data && &div&{data}&/div&
当你的render不需要数据,先渲染dom结构,就在componentDidMount操作。
render() {
const { data } = this.props
&span&我要先渲染&/span&
&span&{data || ''}&/span&
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
这与React组件的生命周期有关,组件挂载时有关的生命周期有以下几个:
constructor()
componentWillMount()
componentDidMount()
上面这些方法的调用是有次序的,由上而下,也就是当说如果你要获取外部数据并加载到组件上,只能在组件"已经"挂载到真实的网页上才能作这事情,其它情况你是加载不到组件的。
componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
constructor被调用是在组件准备要挂载的最一开始,所以此时组件尚未挂载到网页上。
componentWillMount方法的调用在constructor之后,在render之前,在这方法里的代码调用setState方法不会触发重渲染,所以它一般不会用来作加载数据之用,它也很少被使用到。
一般的从后台(服务器)获取的数据,都会与组件上要用的数据加载有关,所以都在componentDidMount方法里面作。虽然与组件上的数据无关的加载,也可以在constructor里作,但constructor是作组件state初绐化工作,并不是设计来作加载数据这工作的,所以所有有副作用的代码都会集中在componentDidMount方法里。
补充一下,Redux作初始数据载入时,是可以不需透过React组件的生命周期方法,大致的方式如下代码:
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './App'
// reducer
function items(state = [], action) {
switch (action.type) {
case 'LOAD_ITEMS':
return [...action.payload]
return state
// 创建store
const store = createStore(items)
fetch('http://localhost:8888/items', {
method: 'GET'
.then((response) =& {
// ok代表状态码在200-299
if (!response.ok) throw new Error(response.statusText)
return response.json()
.then((itemList) =& {
// 作dispatch动作,载入外部数据完成之后
store.dispatch({ type: 'LOAD_ITEMS', payload: itemList })
.catch((error) =& { throw new Error(error.message) })
// React组件加载到真实DOM上
ReactDOM.render(
&Provider store={store}&
&/Provider&, document.getElementById('root'))
为何可以这样作的原因,是Redux的store中的状态有一个最初始的值(reducer上传参里的默认值),组件先初始化完成,接著异步的fetch用promise语法,在作完外部数据加载后,发送动作出来,此时reducer更动store里的状态,react-redux绑定器会触发React组件的重渲染,所以组件上数据会自动更新。
有问题再问吧,代码写得简略但测试过是可执行的。
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:

我要回帖

更多关于 react purecomponent 的文章

 

随机推荐