React入门

Author Avatar
ahscuml 7月 23, 2019
  • 在其它设备中阅读本文章

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

参考资料

什么是JSX

jsx

render方法

  • React.js中一切皆组件。一个组件类必须要实现一个 render 方法,这个 render 方法必须要返回一个 JSX 元素。但这里要注意的是,必须要用一个外层的 JSX 元素把所有内容包裹起来。返回并列多个 JSX 元素是不合法的
  • 在 JSX 当中你可以插入 JavaScript 的表达式,表达式返回的结果会相应地渲染到页面上。表达式用 {} 包裹。
    • 利用JSX可以增加一些逻辑性的东西,或者组合一些内容
  • 自定义的组件都必须要用大写字母开头,普通的 HTML 标签都用小写字母开头。
  • 通过在其它地方使用组件的标签,我们就可以插入一个组件,这样子在这个地方就会调用标签组件的render方法,非常利于组件的重复利用,多个不同的组件可以组成组件树(构建一个页面的逻辑)
  • 为 React 的组件添加事件监听是很简单的事情,你只需要使用 React.js 提供了一系列的 on 方法即可。React.js 会给每个事件监听传入一个 event 对象,这个对象提供的功能和浏览器提供的功能一致,而且它是兼容所有浏览器的。React.js 的事件监听方法需要手动 bind 到当前实例,这种模式在 React.js 中非常常用。这些 on 的事件监听只能用在普通的 HTML 的标签上,而不能用在组件标签上
  • bind的作用:如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。

state与props

  • 一个组件的显示形态是由这个组件的数据状态(state)和配置参数(props)决定的
  • state
    • state 的主要作用是用于组件保存、控制、修改自己的可变状态。state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制的数据源。state 中状态可以通过 this.setState 方法进行更新,setState 会导致组件的重新渲染。
    • setstate:setState 方法由父类 Component 所提供。当我们调用这个函数的时候,React.js 会更新组件的状态 state ,并且重新调用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上。它接受一个对象或者函数作为参数。
    • 当你调用 setState 的时候,React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。
    • 并不是每一次调用setState方法都会重新调用render方法,而是将对同一state的修改集合到一起再去同一渲染
    • React中的setState方法:setState是异步执行的,所以需要一些方法来控制
    • props
      • props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props,否则组件的 props 永远保持不变
      • 每个组件都可以接受一个 props 参数,它是一个对象,包含了所有你对这个组件的配置。
      • 在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为 props 对象的键值
      • React.js 也提供了一种方式 defaultProps,可以方便的做到默认配置。
      • props 一旦传入进来就不能改变。
      • 组件的使用者可以主动地通过重新渲染的方式把新的 props 传入组件当中,这样这个组件中由 props 决定的显示形态也会得到相应的改变。

React组件生命周期

  • React
    • JavaScript箭头函数
    • bind,如果你想在事件函数当中使用当前的实例,你需要手动地将实例方法 bind 到当前实例上再传入给 React.js。 相当于通过bind(this)来完成一个绑定当前实例的工作,方便在方法内调用实例的方法以及state状态或者props
    • 挂载阶段的组件生命周期
      • 挂载的概念:React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载
      • 构建组件的生命周期
        • -> constructor()
        • -> componentWillMount()
        • -> render()
        • -> componentDidMount()
      • 生命周期中的作用
        • 我们一般会把组件的 state 的初始化工作放在 constructor 里面去做;
        • componentWillMount:在 componentWillMount 进行组件的启动工作,例如 Ajax 数据拉取、定时器的启动;
        • componentWillUnmount:组件从页面上销毁的时候,有时候需要一些数据的清理,例如定时器的清理,就会放在 componentWillUnmount 里面去做。
        • componentDidMount: 一般来说,有些组件的启动工作是依赖 DOM 的,例如动画的启动,而 componentWillMount 的时候组件还没挂载完成,所以没法进行这些启动工作,这时候就可以把这些操作放在 componentDidMount 当中。
    • 更新阶段的组件生命周期
      • componentWillReceiveProps
      • componentWillUpdate
      • render
      • componentDidUpdate

React渲染机制解析

  • 渲染过程:在页面一开始打开的时候,React会调用render函数构建一棵Dom树,在state/props发生改变的时候,render函数会被再次调用渲染出另外一棵树,接着,React会用对两棵树进行对比,找到需要更新的地方批量改动。
  • Diff算法:Diff算法只会对同层的节点进行比较。DOM结构介绍
    • 假设1:两个相同的组件产生类似的DOM结构,不同组件产生不同DOM结构
    • 假设2:对于同一层次的一组子节点,它们可以通过唯一的id区分
  • 比较节点类型
    • 节点类型相同
      • DOM元素类型:只改变需要改变的属性
      • React组件类型:触发更新过程
        • shouldComponentUpdate
        • componentWillReceiveProps
        • componentWillUpdate
        • render
        • componentDidUpdate
    • 节点类型不同:直接删除旧节点,创建新节点

点赞按钮的例子

利用state存储状态例子

// 利用state存储状态
class LikeButton extends Component {
  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    return (
      <button onClick={this.handleClickOnLikeButton.bind(this)}>
        {this.state.isLiked ? '取消' : '点赞'} 👍
      </button>
    )
  }
}

维持组件可重复利用

class LikeButton extends Component {
  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    // 设置了渲染的内容,方便后期更改
    const likedText = this.props.likedText || '取消'
    const unlikedText = this.props.unlikedText || '点赞'
    return (
      <button onClick={this.handleClickOnLikeButton.bind(this)}>
        {this.state.isLiked ? likedText : unlikedText} 👍
      </button>
    )
  }
}

利用props来重用组件

class Index extends Component {
  render () {
    return (
      <div>
        <LikeButton likedText='已赞' unlikedText='赞' />
      </div>
    )
  }
}

如何设置默认值

class LikeButton extends Component {
  // 在这里设置默认值
  static defaultProps = {
    likedText: '取消',
    unlikedText: '点赞'
  }

  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    return (
      <button onClick={this.handleClickOnLikeButton.bind(this)}>
      // 设置过默认值这里就不用再进行判断了
        {this.state.isLiked
          ? this.props.likedText
          : this.props.unlikedText} 👍
      </button>
    )
  }
}

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://ahscuml.github.io/React入门/