React.js 小书看完的心得

React.js 小书看完的心得

互联网上的宝藏还真是多,React.js小书就是这样一个短小精悍。。。。。。

前天趁着双十一不到半价购入了高程4,到手就翻了200多页,写的确实比上一版好多了,删减了很多没有必要的内容,又要掀起一波JavaScript的新高潮了。

话说从夏天开始折腾起React.js之后,一直没闲着,有事没事就看两眼和搜搜React的相关信息。互联网上的宝藏还真是多,React.js小书就是这样一个短小精悍却很实用的教程,带着读者自己写出来了ReactReact-redux,借此加深对于React的理解。

作者是胡子大哈,点开知乎一看,签名是本人已经永久退出知乎;React.js小书的链接的域名部分是http://huziketang.mangojuice.top/,点进去是一个胡子课堂,但是链接都已经失效,没有实质内容;点开主域名http://www.mangojuice.top/一看,是一个没有内容的“HuoLuoBo的博客”。从React小书的内容来看,请了几位大厂的工程师来为这本小书提意见,可见这作者也是一名曾经的前端大佬。

不知道大佬这本书写于什么时候,但从安装React那一节中可以看到,当时的React界面与现在我用的React(16版)有所不同,所以估计成书也有些年月了。不过考虑到前端日新月异的发展速度,可能实际时间也没多久。花了两天功夫仔细看完和敲完代码,把自己的一些感想和心得记录下来。

JSX原理

兼听则明确实有道理。本来还只是朦胧的对JSX有点感觉,这里作者直接指出一个DOM元素的信息就是三个:标签名,属性,子元素,所以一个DOM元素就可以拆解成为一个JavaScript对象,类似于:

{
  tag: 'div',
  attrs: { className: 'box', id: 'content'},
  children: [
    {
      tag: 'div',
      arrts: { className: 'title' },
      children: ['Hello']
    },
    {
      tag: 'button',
      attrs: null,
      children: ['Click']
    }
  ]
}

其中每一个元素又可以通过React.createElement()来构建,这就是JSX的本质。这样还有一大好处,就是把DOM元素的信息与HTML这个形式进行解绑,可以把信息渲染到各种媒介上,这也是为什么对于日常编写WEB应用,除了有一个核心的React.js库,还需要另外一个react-dom库的原因。

一些小心得

记录一下里边提到的几个小要点

灵活控制props.children的内容

React里,可以直接在组件标签内传入其他组件或者原生HTML代码,在组件内部就可以通过props.children来获取传入的内容,这个传入的内容实际上是一个数组,所以可以用数组索引来控制渲染哪一些,还可以把这些children渲染在不同的地方,非常灵活。

dangerouslySetInnerHTML属性

正常情况下,所有表达式在计算的时候如果最后是打印出来,都会被自动转义,React不会允许直接插入HTML内容,但是使用这个属性就可以,例子如下:

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

要给这个属性一个对象,对象的__html属性就是要渲染进去的内容,相当于innerHTML,这个属性千万不要滥用,或者干脆说平时就压根别用。

利用第三方库prop-types来进行类型验证

究竟props传了什么玩意进来,有的时候就不好控制,因此React提供了一个库,专门用于验证props的类型。
用法是固定的在类里边配置一个静态属性,名称也是固定的,如下:

class Comment extends Component {
  static propTypes = {
    comment: PropTypes.object,
    content: PropTypes.string.isRequired
  }

  ......
  
}

propTypes是一个对象,对象的属性名就是props中传入的属性名,值是对应的类型,后边可以加上.isRequired来强制必须传入该属性。

默认defaultProps

前边说了可以验证属性和设置,但即使做了验证也挡不住就是不给传,这个时候可以给props设置默认值,也是通过一个特殊的静态变量:

class Comment extends Component {
  static defaultProps = {
    likedText: '取消',
    unlikedText: '点赞'
  }

  ......
  
}

这样如果props中没有对应的属性的话,就会采用默认值,再也不用怕瞎传属性啦。

context属性

这东西就像WEB容器里的容器全局变量一样,绑一个东西就可以从另外一个地方取回来。不过Reactcontext不像WEB容器那么直接,而是要使用特殊的写法,还必须得搭配类型验证。先来看看如何设置context

class Comment extends Component {
   //这是特定的变量名称,必须写这个,否则无法使用context特性
   static childContextTypes = {
    themeColor: PropTypes.string
  }

  //这是特定的方法名称,必须这么写。这个函数看着是get,实际上是将内容放入到context,并且再返回context
  getChildContext () {
    return { themeColor: this.state.themeColor }
  }
  ......
  
}

WEB容器一样,在某个地方给设置上了属性和值,在其他的地方就能取出来,在其他的组件中取出来的方法也需要搭配类型验证,然后使用this.context.attrname即可:

class Title extends Component {
  static contextTypes = {
    themeColor: PropTypes.string
  }

  render () {
    return (
      <h1 style={{ color: this.context.themeColor }}>React.js 小书标题</h1>
    )
  }
}
  ......
  
}

Redux库实际上就是附着在context上,不然你以为有什么魔法能够实现全局状态吗。

后记

亲自写完一个Redux的实现之后,发现就是利用装饰器和函数式编程的特性,不断的将组件分离成无状态组件和依赖react基础库之外,需要进行逻辑处理数据的组件,然后再通过高阶组件特性结合起来。对Redux需要编写一个reducer的特点也更加清晰了。虽然看上去React要写的代码好像比原来使用Vue.js要复杂一点,但相比之下数据的处理和流动非常清晰。

今天听说有了hook之后,高阶组件也用的少了,不知道是什么套路,hook我也要去学习一下才行。

最后再提一句,全面转向Markdown来写博客真的太爽了。

LICENSED UNDER CC BY-NC-SA 4.0
Comment