组件化和 React几点问题

255 阅读2分钟

1. 对组件化的理解

首先谈,组件封装:封装数据、视图、变化逻辑;
其次说,组件复用:通过props传值

2. JSX的本质

第一,JSX的语法。它以html标签的形式存在,引入js变量和表达式,if语法,for循环,style样式和className,并且支持事件
第二,JSX语法根本无法被浏览器解析,开发环境会把JSX语法解析成js对象
第三,通过React.createElement方法把JSX语法解析成JS代码。方法参数接收(标签名,属性,子元素)。如何解析的?
解析前:

    // render函数
    render() {
      const list = this.props.list
      return (
        <ul>
          {list.map((item, index) => {
            return <li key="index">{item}</li>
          })}
        </ul>
      )
    }

解析后:

    // 解析后
    function render() {
      const list = this.props.list
      React.createElement('ul',
        null,
        list.map((item, index) => {
          return React.createElement('li', { key: index }, item)
        }))
    }

3. JSX和vdom的关系

  1. 关于为什么要用vdom?JSX模板需要解析成html,数据驱动视图
  2. 其中React.createElement()和h()函数都生成vnode【见上个问题】 第一次渲染是在ReactDOM.render(,document.getElementById(‘root’))的时候,通过dispatch(container,vnode)把vnode渲染在容器上。
// 第一次 dispatch(container,vnode)
ReactDOM.render(<App />, document.getElementById('root'))

重新渲染是在使用setState()修改data的时候触发re-render生成新的newVnode,然后通过dispatch(vnode,newVnode)用新生成的替代旧的。

    addTodo(title) {
        const currentList = this.state.list
        // 重新 dispatch(vnode,newVnode)
        this.setState({
          list: currentList.concat(title)
        })
    }
  1. 关于生成的vnode的本质就是js对象,对于我们平常使用的标签(如div,p等),React.createElement()的时候生成对应的标签。
    对于自定义的组件,则生成自定义组件的实例,通过实例的render函数再次生成新的vnode,依次的循环迭代下去,直到变成最底层我们平常使用的标签。
    带自定义组件的render:
    // render函数
    render() {
      const list = this.props.list
      return (
        <div>
          <p>普通标签</p>
          <List data={this.state.list} />
        </div>
    )}

自定义组件解析后:

    // 解析后
    function render() {
      const list = this.props.list
      React.createElement('div',
        null,
        React.createElement('p', null, '普通标签'),
        React.createElement(List, { data: this.state.list })
        // List是自定义组件,一般是先初始化List组件的实例,然后调用实例的render函数生成vnode,依次循环,知道没有自定义组件
        // var list = new List({data:this.state.list})
        // var vnode = list.render()
      )}

4.setState的过程

首先,setState是异步的,为了避免多次修改引发dom的re-render。
其次,每个组件都继承了顶层React.Component组件中的renderComponent方法,重新执行实例的render
最后,根据render返回的newVnode和preVnode进行对比,通过dispatch函数新的节点替代旧的节点

5.最后关于react和vue的区别