最近尝试使用React做一个小项目(todolist),现在虽然做完了,但其实代码的实现实在是烂透了,比如leancloud的数据获取、另外由于组件划分设计得有点怪,而且页面的交互细节太依赖数据,数据的传递及管理并不如人意,很多时候要经过中间层,这让我感觉很别扭,以至于萌生加入redux来优化这个项目的念头。
这次会先充分了解react及redux的机制,再来完成项目。
react 与 JSX
在我刚使用react的时候,最鲜明的特征应该就是可以在js里写“HTML”了,这其实就是JSX,而且这写看似HTML的字符串也并不是HTML
-
什么是JSX
JSX是一种类XML语言,全称是JavaScript XML,它是对javaScript的一种扩展。
在react里,我们可以用JSX直观地定义出一个UI组件的结构,当然其实我们也可以不用JSX来写,因为最终JSX也会经过转义,成为一个描述DOM结构的对象。但 react作者 还是强烈建议我们使用JSX,原因上面也有说---直观。简明的代码结构更利于开发和维护,JSX的特点能让我们在构建复杂的树形结构时比函数调用和对象字面量更易读。
//使用JSX class Sayhi extends React.Component{ render(){ return( <div> <div> <h1>hello World</h1> <p> I am description</p> </div> </div> ) } } ReactDom.render(<Sayhi/>,document.getElementById('root')) // 不使用JSX class Sayhi extends React.Component{ render(){ return( React.createElement( "div", null, React.createElement( "div", null, React.createElement( "h1", null, "hello World" ), React.createElement( "p", null, " I am description" ) ) ) ) } } ReactDom.render(<Sayhi/>,document.getElementById('root'))
-
JSX使用要记
1.所有的标签都需要闭合。
2.自定义组件的声明变量采用首字母大写
3.JSX内表达式需用
{}
包起来4.比较特殊的属性如
class
在JSX里需写成className
5.每段JSX里的XML只能有一个根元素
JSX与 Virtual DOM
上面讲到JSX最终会被编译为一个描述DOM结构的对象,这里就引出了一个React的重要思想----Virtual DOM。
我们都知道真实的DOM并不是JavaScript的内置对象,而是浏览器提供给我们的接口。而React中的Virtual DOM是存在于内存的,显而易见,让JavaScript操作内存比操作DOM节点快得多。react就是利用Virtual DOM来减少对实际DOM的操作从而提升性能。
react通过diff算法,对比虚拟DOM变化前后的变化,来进行局部更新。比较特殊的是:传统的diff算法时间复杂度为O(n^3),而React的时间复杂度是O(n),这样的设置提高了React的性能,但是不可避免地会带来一定的代价。
举一个栗子
上面两个树行结构的DOM是变化前后的结构,其中A从father的子元素变为B的子元素,在react的diff算法中,它是无法辨认这种变化的,它会认为A从页面结构中卸载了,而新的DOM结构内的A是新的组件元素。
1.不可缺少的key
因此日常开发中,我们动态生成元素的时候,需要给每个元素带上一个key,这也是为了给每个元素带上一个唯一的标记,便于react识别。
而我们动态生成元素大多数都是通过map一个数组,这里就很喜欢给每个元素的key标记为他们的index,其实这样是不对的做法,我们不能保证这个数组不会临时增加或者减少一个节点,这个时候每个元素的key也会发生变化,那么我们建立这个key的意义将不存在了,所以,key还要是稳定的
[注:上面的例子比较极端,React官方也不建议DOM节点跨层级的操作]
2.占位的组件
先来一段代码
this.state.isCompleted?<Completed> : null
这段代码通过一个变量来控制组件的出现或消失,这种情况不需要加一个key来辨别,因为这里已经有null
为<Completed>
占位了。
3.组件对比
对于组件变化前后的对比策略,react会首先对比俩组件的类型,如果类型一致,则继续对比其他内容;若类型不一致,则判断该组件为dirty component,然后替换整个组件(包括它的子节点)
最后,本人才疏学浅,所记录的笔记仅仅是为了巩固记忆,加深印象,难免有点肤浅,望见谅。