使用react要注意一点,所有的页面都应该通过组件实现。(Everything in React is a component)
react使用的js为中心,把”HTML”放到js里的组件化思想,是现在前端组件化实践中比较优秀的一个方案。
所谓组件,就是状态机器。
React将用户界面看做简单的状态机器。当组件处于某个状态时,那么就输出这个状态对应的界面。通过这种方式,就很容易去保证界面的一致性。
在React中,你简单的去更新某个组件的状态,然后输出基于新状态的整个界面。React负责以最高效的方式去比较两个界面并更新DOM树。
这种组件模型简化了我们思考的方式:对组件的管理就是对状态的管理。
拿我们业务中使用的框架举例:
ttm - MVC的思考模式 - 视图-数据-控制器的分离
react - 组件化的思考模式 - UI功能模块之间的分离对于MVC开发模式来说,开发者将三者定义成不同的类,实现了表现,数据,控制的分离。开发者更多的是从技术的角度来对UI进行拆分,实现松耦合。对于React而言,则完全是一个新的思路,开发者从功能的角度出发,将UI分成不同的组件,每个组件都独立封装。
何为组件?
React认为一个组件应该具有如下特征:
可组合(Composeable):一个组件易于和其它组件一起使用,或者嵌套在另一个组件内部。如果一个组件内部创建了另一个组件,那么说父组件拥有(own)它创建的子组件,通过这个特性,一个复杂的UI可以拆分成多个简单的UI组件;
可重用(Reusable):每个组件都是具有独立功能的,它可以被使用在多个UI场景;
可维护(Maintainable):每个小的组件仅仅包含自身的逻辑,更容易被理解和维护;
可测试(Testable):因为每个组件都是独立的,那么对于各个组件分别测试显然要比对于整个UI进行测试容易的多。
在写组件的时候,要注意几点:
react里有两种数据:props,state.
state - state是组件内部的数据,可以在组件内部改变该数据。props-从外界传到组件的数据,不可在组件内改变。
props的存在支持了组件的可复用性。
jsx语言中,我们可以直接使用html标签。
1 | <div className="foo" /> |
但是class要改写为className。
也可以直接引用封装的组件
1 | <MyComponent someProperty={true} /> |
jsx中支持直接通过{}引用属性。
1 | <Person name={window.isLoggedIn ? window.name : ''} /> |
我们通过ReactDOM.render()把jsx语言解析为html。
JSX也可通过React API直接替代:
1 | React.creatElement('h1', null, 'hello') |
通过JSX或API,react生成一个Element,实际就是一个object
JSX => virtual React elements => native DOM elements
React如何将JSX解析出来的element生成实际能被浏览器识别的native DOM呢?
即React.render()
render方法里,先用ReactDOMComponent实例化element,在ReactDOMComponent的mountComponent方法解析element,使用DOM API插入浏览器
优化React.render()支持creatClass
ReactCompositeComponentWrapper,利用 props实例化一个component,用此component生成的element继续优化前的步骤 (先用ReactDOMComponent实例化element,在ReactDOMComponent的mountComponent方法解析element,使用DOM API插入浏览器)
支持纯函数组件
在render中加上对element.type是否为function的判断,如是直接返回(new element(element.props)).render()
render之后做了什么?
组件render后通过createElement将JSX转为virtual DOM
React.render首先判断是否是第一次渲染,如果是,将内部element(结合了props/做了function判断)塞进ReactDomElement实例里,调用内部方法结合DOM API插入浏览器中;否则,判断两次element元素的不同,对原有元素进行修改
setState之后做了什么?
容器组件和渲染组件-组件的处理层和渲染层的分离:渲染组件尽可能是无状态组件,容器组件则是有状态的纯类。条件渲染,多个条件渲染组件叠加,recompose, 条件函数可控,conditionalRenderingFn, EitherComponent,withMaybe, withEither
render prop component - this.props.children()
也可使用HOC替代
参考: