React——第二阶段

根据胡子大哈的文章学习,感谢大胡分享
胡子大哈-第二阶段

一、理解状态管理

状态管理是为了解决一个问题:

如何高效的管理被多个组件依赖或影响的状态?

state和props都是状态池,里边的字段就是状态。
当父组件中有多个子组件需要某个状态,那么这个时候,这个状态要保存在父组件来达到共享。
但是,如果父组件只是爷爷组件的其中一个孩子,而其他的父组件的兄弟组件也需要这个状态。那么这个状态就要保存在爷爷组件。
如上循环,这种将某个状态往外层放的情况,叫做状态提升。
在实际项目中,可能遇到,嵌套较深的两个组件依赖同一个状态的情况,这个时候如果使用状态提升的方法,就需要把这个状态提升到很外层的组件里,显然不是一个好方法

Redux就是解决这个问题的,关于它,将在下一阶段复习

一般的不被多个组件依赖的状态,内部保存就行。

二、生命周期

1.组件挂载
过程:
实例化组件(constructor())-->调用render生成元素对象(react.js)-->将元素对象构建成dom对象(reactDOM)-->插入页面

以上就是挂载。
抽象一下,就是这个过程

-> constructor()
-> render()
-> 构造dom
-> 插入页面

2.挂载生命周期与控制钩子

  • 为了更好的控制挂载过程

React.js提供了两个钩子
componentWillMount()componentDidMount()
两个方法在组件内部定义,
在组件的render之前调用componentWillMount()
在DOM元素插入页面后调用componentDidMount()
抽象下

-> constructor()
   -> componentWillMount()
-> render()
-> 构造dom
-> 插入页面
   -> componentDidMount()
  • 完善过程——删除页面钩子

完善上边抽象的过程

-> constructor()
   -> componentWillMount()
-> render()
-> 构造dom
-> 插入页面
   -> componentDidMount()
...
-> 将从页面中删除
-> 已从页面中删除

React.js同样控制了这个过程,componentWillUnmount()

-> constructor()
   -> componentWillMount()
-> render()
-> 构造dom
-> 插入页面
   -> componentDidMount()
...
-> 将从页面中删除
 -> componentWillUnmount()
-> 已从页面中删除

注:
删除一个组件是很经常的,一个标签的隐藏和显示{this.state.isShow ? <App /> : null}类似这样的逻辑。

  • 挂载过程的一些说明
    constructor:初始化工作,比如state
    componentWillMount:一些组件启动时的行为,比如Ajax、定时器
    componentWillUnmount:清场工作,比如取消定时器,防止各种错误,比如内存泄漏。

3.更新阶段组件生命周期

  • 更新过程:
    setState --> render --> dom --> 插入页面
    要理解这个过程,就需要对virtual--DOM有比较深刻的认识,这些将在第四阶段复习。
    接下来,大概了解下更新过程和这个过程中的钩子

  • 钩子函数
    shouldComponentUpdata(nextProps, nextState):通过这个方法,控制组件是否重新渲染。
    componentWillReceiveProps(nextProps):组件从父组件接收新的props之前调用
    componentWillUpdate():组件开始重新渲染之前调用
    componentDidUpdate():组件重新渲染并且把更改变更到真实的DOM以后调用

4.小总结
这里引用一些网上文章的内容
下文引用自NsNe的博客

每个组件都有几个生命周期函数,以will为前缀的函数是在发生某些事之前调用,以did为前缀的是在发生某些事之后调用

1.Mounting
如下这些方法在组件实例被创建和被插入到dom中时被调用。

  • constructor()

  • componentWillMount()
      此方法在mounting之前被立即调用,它在render()之前调用,因此在此方法中setState不会触发重新渲染。此方法是服务器渲染中调用的唯一的生命周期钩子,通常我们建议使用constructor()。

  • render()

  • componentDidMount()
      此方法在组件被mounted之后立即被调用,初始化dom节点应该在此方法中,如果需要从远端健在数据,这里是实例化网络请求的好地方,此方法中setState会触发组件重新渲染。

Updating
props和state的改变产生更新。在重新渲染组建时,如下的方法被调用

  • componentWillReceiveProps()
      一个已经mounted的组件接收一个新的props之前componentWillReceiveProps()被调用,如果我们需要更新state来响应prop的更改,我们可以在此方法中比较this.props和nextProps并使用this.setState来更改state。
      注意,即使props没有改变,React也可以调用这个方法,因此如果你只想处理改变,请确保比较当前值和下一个值。当父组件导致你的组件重新渲染时,可能会发生这种情况。
      React在组件mounting期间不会调用此方法,只有在一些组件的props可能被更新的时候才会调用。调用this.setState通常不会触发componentWillReceiveProps。
  • shouldComponentUpdate()
      使用此方法让React知道组件的输出是否不受当前state或props更改的影响。默认行为是在每次state更改时重新渲染组件,在大多数情况下,我们应该默认改行为。
      当接收到新的props或state时,shouldComponentUpdate()在渲染之前被调用。默认返回true,对于初始渲染或使用forceUpdate()时,不调用此方法。返回false不会阻止子组件的state更改时,该子组件重新渲染。
      如果shouldComponentUpdate()返回false,那么componentWillUpdate(),render()和componentDidUpdate()将不会被调用。在将来,React可能将shouldComponentUpdate()作为提示而不是strict指令,返回仍然可能导致组件重新渲染。
  • componentWillUpdate()
      当接收新的props或state时,componentWillUpdate()在组件渲染之前被立即调用。使用此函数作为在更新发生之前执行准备的机会。初始渲染不会调用此方法。注意:这里不能调用this.setState()(如果调用会怎么样?好奇心很重呀,试了一下,会产生死循环,一直更新。。。)。如果我们需要更新state以响应props的更改,我们应该使用componentWillReceiveProps()
  • render()
  • componentDidUpdate()
      此函数在更新后立即被调用。初始渲染不调用此方法。
      当组件已经更新时,使用此操作作为DOM操作的机会。这也是一个好的地方做网络请求,只要你比较当前的props和以前的props(例如:如果props没有改变,可能不需要网络请求)。

Unmounting
当从dom中移除组件时,这个方法会被调用

  • componentWillUnmount()
      此函数在组件被卸载和销毁之前被立即调用。在此方法中执行一些必要的清理。例如清除计时器,取消网络请求或者清理在componentDidMount中创建的任何DOM元素。

三、ref

流行的前端大框架,基本上都避免了绝大部分的DOM更新操作,jQ基本88。

但是,框架提供的功能并不能满足所有的需求。所以,有时候还是要和DOM打交道。

比如动态获取某个元素尺寸,然后做动画。

React.js的ref属性
通过这个属性,可以获取已经挂载的元素对应的真实DOM节点。
用法:

<Index ref={(Index) => this.index = Index} />

当然,一般是标签,不是组件,这里只是示例。

布局

一般情况下,在写页面的时候,会有很多容器标签,来给页面布局。组件化开发,同理,就会有一些容器组件,用来布局。

如何方便的使用这些组件?既然是容器组件,那么调用组件的时候,是不是要传入容器里的内容,然后让容器渲染呢?

通过porps,在字段中书写JSX显然是不方便的。React.js提供了props.children属性,它是一个数组,保存了调用组件时,组件闭合标签内的结构。
在组件内部,就可以直接使用这个属性了。

class Layout extends Component {
  render () {
    return (
      <div className='two-cols-layout'>
        <div className='sidebar'>
          {this.props.children[0]}
        </div>
        <div className='main'>
          {this.props.children[1]}
        </div>
      </div>
    )
  }
}

...// 调用的时候
某个组件调用Layout组件
render () {
  return (
    <Layout>
      <div>你们好</div>
      <div>哈哈哈</div>
    </Layout>
  )
}

五、dangerouslySetInnerHTML

为避免xss,React.js将所有通过表达式插入的内容自动转义——>字符串

如何向其中插入HTML结构(innerHTML)?

 <div
      className='editor-wrapper'
      dangerouslySetInnerHTML={{__html: this.state.content}} />

// this.state.content: <div>一个标签</div>

六、style

在标签中,style字段接收一个对象,而不是原生的字符串。
在对象中,对应css字段命,使用小驼峰命名。eg:background-color——>backgroundColor

因为style是一个对象,我们就可以使用状态池中的状态了,很方便。

七、数据验证

1.理解验证的重要性
多人协作,组件复用,没有验证,健壮性就太差。

2.React.js的验证机制

  • 引入prop-types
  • 定义propTypes字段,对输入进行检查
  • propTypes提供的参数
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
等等

更多点此查看官网

多人协作开发,写类型检查吧,省事好维护

(完)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,813评论 1 18
  • 本笔记基于React官方文档,当前React版本号为15.4.0。 1. 安装 1.1 尝试 开始之前可以先去co...
    Awey阅读 7,661评论 14 128
  • It's a common pattern in React to wrap a component in an ...
    jplyue阅读 3,260评论 0 2
  • “你刚才说穿垮裤啊?对呀,我生活中穿的很舒服就好了,对。然后就是他们好像会说,如果说是演员或者做演艺的,好像衣服不...
    戴梦阅读 256评论 0 0
  • ——❤—— 你是否 还记得 当初见我的第一眼 ——❤——
    七柒v阅读 604评论 0 1