Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React思想要点 #7

Open
zhouzhili opened this issue Apr 1, 2019 · 0 comments
Open

React思想要点 #7

zhouzhili opened this issue Apr 1, 2019 · 0 comments

Comments

@zhouzhili
Copy link
Owner

react 是一个优秀的前端框架,虽然平常都是用的 vue,但是 react 的大名也是如雷贯耳,受网上一些教程的启发,决定自己简单实现一遍 react,对它的工作方式以及原理也有了更深的了解

React 要点

react 主要的要点就是 JSX 和虚拟 DOM,

  1. JSX 是一种扩展语法,用于在 js 代码中编写 HTML 片段,如下:
const div = <div className="main">Hello World</div>

JSX 语法通过 babel 转义之后本质是调用函数来处理的,例如上面的代码经过 Babel 处理之后在 React 中会转成以下代码:

const div = React.createElement(
    'div', 
    { className: 'main' },
    'Hello World'
)

除了使用React.createElement()方法,我们也可以使用自己定义的函数来编译JSX,在**.babelrc**中配置下就可以

{
    "presets": ["env"],
    "plugins": [
        ["transform-react-jsx", {
            "pragma": "React.createElement"
        }]
    ]
}

transform-react-jsx 下面的pragma就是转换时使用的函数,我们可以换成其它的函数,只要在全局中存在这个函数名就可以。函数的参数为以下:tag(标签名),attrs(属性), children(子节点)

function createElement( tag, attrs, ...children ) {
    return {
        tag,
        attrs,
        children
    }
}

所以我们在开发过程中写的JSX代码,最后会被Babel编译成{tag,attrs,children}对象,我们只需要根据这个对象来创建相应的节点,设置属性,对其子元素递归调用render函数就可以了,最后挂载到节点上,完成渲染。

节点一般有以下几种情况:

  • 数字或者文本内容:这种直接创建文本节点就可以

  • 函数或者类:这种说明节点是一个组件,我们直接调用该组件的render方法获取其返回的JSX内容然后再继续进行解析即可(这也是为什么React组件必须实现Render方法或者必须返回JSX内容的原因)

  1. 虚拟DOM主要就是使用JS语法模拟出来的DOM对象,与原生DOM要素相比更加轻量,也方便使用JS来渲染节点。

    要保持数据更新之后视图随之变化,我们需要约定一种数据更新方法,以便我们能够在数据更新之后调用render方法来更新视图。所以React规定更新数据只能用setState ,这样我们就能在state变更之后调用render函数对数据进行跟新,setState方法简易实现如下:

    setState(newState) {
        this.state = Object.assign(this.state, newState)
        render(this)
     }

    在元素更新的时候我们有很多可以优化的地方,不用每次更改一点数据就全部重新渲染,我们可以只更新更改的部门,这就涉及到diff算法了,我们可以对已有的虚拟DOM和数据更改后的虚拟DOM进行对比,找出差异的部门进行更新,具体则不做描述。

  2. 虚拟DOM的思想不仅能运用在HTML上,只要与视图相关的都可以使用,因为React的思想就是view=render(data). 我们只要实现我们自己的render函数,根据{tag,attrs,children}来解析我们的JSX就可以,不必局限于DOM元素,canvas元素或者我们自定义的绘图要素都可以,唯一的限制是你的想象力。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant