ReactJs小书笔记(二)

ReactJs小书笔记(二)

ReactJs小书官方文档:传送门

17 前端应用状态管理——状态提升

  1. 概念:当平级的组件之间的需要进行数据传递的时候,需要将组件之间的共享的状态交给组件附近最近的父节点保管,然后通过 props 把状态传递给子组件,实现组件之间的数据共享;
  2. 总结:当某个状态被多个组件依赖或者影响的时候,就把该状态提升到这些组件的最近公共父组件中去管理,用 props 传递数据或者函数来管理这种依赖或着影响的行为;
  3. 问题:一旦发生状态提升,就需要修改原来保存这个状态的组件的代码,也要把整个数据传递路径经过的组件都修改一遍,好让数据能够一层层地传递下去;这样对代码的组织管理维护带来很大的问题。

18 挂载阶段的组件生命周期(1)

  1. 组件初始化阶段
    • constructor():(构造器)初始化组件;
    • componentWillMount():组件挂载开始之前,也就是在组件调用 render 方法之前调用;
    • render(): 将构造好的 DOM 元素挂载到页面;
    • componentDidMount():组件挂载完成以后,也就是 DOM 元素已经插入页面后调用;
  2. 组件的删除阶段
    • 即将从页面中删除
    • componentWillUnmount():组件对应的 DOM 元素从页面中删除之前调用;
    • 从页面中删除

19 挂载阶段的组件生命周期(2)

利用生命周期函数实现一个时钟的应用:

import React, { Component } from 'react';

class Clock extends Component {
  constructor () {
    super()
    this.state = {
      date: new Date()
    }
  }
  componentWillMount () {
    this.timer = setInterval(() => {
      this.setState({ date: new Date() })
    }, 1000)
  }
  render () {
    return (
      <div>
          <p>现在的时间是:</p>
        <h3>
          {this.state.date.toLocaleTimeString()}
        </h3>
      </div>
    )
  }
}

class App extends Component {
  constructor () {
    super()
    this.state = { isShowClock: true }
  }

  handleShowOrHide () {
    this.setState({
      isShowClock: !this.state.isShowClock
    })
  }
  render () {
    return (
      <div>
        {this.state.isShowClock ? <Clock /> : null }
        <button onClick={this.handleShowOrHide.bind(this)}>
          显示或隐藏时钟
        </button>
      </div>
    )
  }
  componentWillUnmount () {
    clearInterval(this.timer)
  }
}

export default App;

20 更新阶段的组件生命周期

  1. shouldComponentUpdate(nextProps, nextState):你可以通过这个方法控制组件是否重新渲染;如果返回 false 组件就不会重新渲染。这个生命周期在 React.js 性能优化上非常有用;
  2. componentWillReceiveProps(nextProps):组件从父组件接收到新的 props 之前调用;
  3. componentWillUpdate():组件开始重新渲染之前调用;
  4. render() :将构造好的 DOM 元素挂载到页面;
  5. componentDidUpdate():组件重新渲染并且把更改变更到真实的 DOM 以后调用;

21 ref 和 React.js中的DOM操作

  1. React.js 中基本不会和DOM直接打交道;React.js 提供了一系列的 on* 方法帮助我们进行事件监听,所以 React.js 当中不需要直接调用 addEventListener 的 DOM API;并且React.js 重新渲染的机制帮助我们免除了绝大部分的 DOM 更新操作;
  2. React.js 当中提供了 ref 属性来帮助我们获取已经挂载的元素的 DOM 节点,可以给某个 JSX 元素加上 ref 属性,如 进入页面实现自动 focus 到输入框:
class AutoFocusInput extends Component {
  componentDidMount () {
    this.input.focus()
  }
  render () {
    return (
      <input ref={(input) => this.input = input} />
    )
  }
}
ReactDOM.render(
  <AutoFocusInput />,
  document.getElementById('root')
)
  1. 组件标签也可以使用 ref 属性,获取该组件的DOM节点;

注意: ReactJs 中能不用 ref 就不用;特别是要避免用 ref 来做 React.js 本来就可以帮助你做到的页面自动更新的操作和事件监听,多余的 DOM 操作其实是代码里面的“噪音”,不利于我们理解和维护。

22 props.children 和容器类组件

  1. 容器类的组件中可以填充任意的内容,其定义了一种外层的结构,如下:
import React, { Component } from 'react';
class Card extend Component {
  constructor () {
    super()
    this.state= {}
  }
  render(
    <div className='card'>
      <div className='card-content'>
        {this.props.content}
      </div>
    </div>
  )
}
ReactDOM.render(
  {/*通过给 Card 组件传入一个 content 属性,这个属性可以传入任意的 JSX 结构。然后在 Card 内部会通过 {this.props.content} 把内容渲染到页面上*/}
  <Card content={
    <div>
      <h2>React.js 小书</h2>
       <div>开源、免费、专业、简单</div>
      订阅:<input />
    </div>
  } />,
  document.getElementById('root')
)
  1. 使用 props.children ,能够使得组件获取所有嵌套在组件中的 JSX 结构,如下:
import React, { Component } from 'react';
class Card extends Component {
  render () {
    return (
      <div className='card'>
        <div className='card-content'>
          {this.props.children}
        </div>
      </div>
    )
  }
}
ReactDOM.render(
  <Card>
    <h2>React.js 小书</h2>
    <div>开源、免费、专业、简单</div>
    订阅:<input />
  </Card>,
  document.getElementById('root')
)
  1. props.children 值打印出来,可以知道其本质是一个数组,因而甚至可以在组件内部把数组中的 JSX 元素安置在不同的地方:
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>
    )
  }
}

23 dangerouslySetHTML 和 style 属性

23.1 dangerouslySetHTML 属性

  1. 出于安全考虑的原因(XSS 攻击),在 React.js 当中所有的表达式插入的内容都会被自动转义,就相当于 jQuery 里面的 text(…) 函数一样,任何的 HTML 格式都会被转义掉,而 React.js 提供了一个属性 dangerouslySetInnerHTML ,可以让我们设置动态设置元素的 innerHTML
class Editor extends Component {
  constructor() {
    super()
    this.state = {
      content: '<h1>React.js 小书</h1>'
    }
  }
  // content中的内容会完全展示,其中 h1 标签被转义了,显示为字符串
  render () {
    return (
      <div className='editor-wrapper'>
        {this.state.content}
      </div>
    )
  }

  // 使用 `dangerouslySetInnerHTML` 属性能够设置动态设置元素的 `innerHTML`
  render () {
    return (
      <div
        className='editor-wrapper'
        dangerouslySetInnerHTML={{__html: this.state.content}} />
    )
  }
}

23.2 style 属性

React.js 中使用 style 属性时,需要把 CSS 属性变成一个对象再传给元素:

<h1 style={{fontSize: '12px', color: 'red'}}>React.js 小书</h1>

其中 style 接受一个对象,这个对象里面是这个元素的 CSS 属性键值对,原来 CSS 属性中带 - 的元素都必须要去掉 - 换成驼峰命名

24 PropTypes 和组件参数验证

  1. 原由:JavaScript 的灵活性体现在弱类型、高阶函数等语言特性上,然而语言的弱类型很容易出 bug,所以在 React.js 中给组件的配置参数加上类型验证;
  2. 安装使用 React 提供的第三方库 prop-types 进行类型验证:npm install --save prop-types
import React, { Component } from 'react'
import PropTypes from 'prop-types'

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object
  }

  render () {
    const { comment } = this.props
    return (
      <div className='comment'>
        <div className='comment-user'>
          <span>{comment.username} </span>:
        </div>
        <p>{comment.content}</p>
      </div>
    )
  }
  1. prop-types 类型验证参数:
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
  1. prop-types 中通过 isRequired 关键字来强制组件某个参数必须传入:
...
static propTypes = {
  comment: PropTypes.object.isRequired
}
...
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 1、什么是react React.js 是一个帮助你构建页面 UI 的库。React.js 将帮助我们将界面分成了...
    谷子多阅读 2,554评论 1 13
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,001评论 0 1
  • ReactJs小书笔记(一) ReactJs小书官方文档:传送门 1 react简介 React.js 不是一个框...
    Haleng阅读 682评论 0 0
  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,214评论 0 9
  • It's a common pattern in React to wrap a component in an ...
    jplyue阅读 3,248评论 0 2