没有网站可以做百度推广吗,怎么做论坛的网站,雅虎搜索引擎中文版,数据中心idc机房本节主要从底层原理上分析下React开发相关的内容和注意事项#xff0c;本节会围绕使用展开#xff0c;而非源码讲解。 Componment详解
什么是组件
在 MVVM架构出现之前#xff0c;组件主要分为两种。
狭义上的组件#xff0c;又称为 UI 组件#xff0c;比如 Tabs 组件、… 本节主要从底层原理上分析下React开发相关的内容和注意事项本节会围绕使用展开而非源码讲解。 Componment详解
什么是组件
在 MVVM架构出现之前组件主要分为两种。
狭义上的组件又称为 UI 组件比如 Tabs 组件、Dropdown 组件。组件主要围绕在交互动作上的抽象针对这些交互动作利用 JavaScript 操作 DOM 结构或 style 样式来控制。这样的逻辑一旦复杂就存在大量的 DOM 操作开发及维护成本相当高。广义上的组件即带有业务含义和数据的 UI 组件组合。这类组件不仅有交互动作更重 要的是有数据与界面之间的交互。然而这类组件往往有较大的争议。在规模较大的场景下我们更倾向于采用分层的思想去处理。
React 的本质核心关心元素的构成 React 组件也可理解为组件元素。组件元素被描述成纯粹的 JSON 对象意味着可以使用方法或是类来构建。React 组件基本上由 3 个部分组成:属性(props)、状态(state)以及生命周期方法。
组件的生命周期
下图是一个详细的数据流图 对上图进行不同阶段的分解后不同操作执行过程如下表所示
First RenderUnmoutPropes changeState changegetDefaultPropscomponentWillUnMountcomponentWillReceivePropsshouldComponentUpdategetInitialStaterendershouldComponentUpdatecomponentWillUpdatecomponentWillMountgetInitialStatecomponentWillUpdaterenderrendercomponentWillMountrendercomponentDidUpdatecomponentDidMountcomponentDidMountcomponentDidUpdate
原码方法详解如下需要注意不同版本的React方法可能不太一样
/*组件再次渲染时在render()渲染前调用即props和state发生变化时会触发此方法*/
componentWillUpdate: function () {
},/*组件再次渲染时在render()渲染后调用*/
componentDidUpdate: function () {
},/*在新节点插入DOM结构之前调用*/
componentWillMount: function () {
},/*在新节点插入DOM结构之后调用*/
componentDidMount: function () {
},/*在组件从DOM中移除时调用*/
componentWillUnmount: function () {
},/*在componentWillUpdate()之前调用用来决定组件是否调用render()来更新返回true和false*/
shouldComponentUpdate(nextProps, nextState){
}创建组件的步骤
以下是一个指引在使用熟练之外基本不用参考如下图流程。 在构造大型组件时一是要考虑复用、二是要考虑其可跳跃性所以一般会以树状结构构建详细的例子可参考 将 UI 视为树
用分离模式来设计组件
虽然可以把一个组件的所有代码写在一个.js文件中但这种方法的复用度不是太好所以一般要设计大型组件时一般会采用分离设计数据UI或数据UI包装器这种设计方式主要依赖了React的
props这种可以共享数据的机制、组件调用时可以传递子元素的属性是一个children数组。 比如下例
定义UI组件
这里只关注样式没有状态数据
import React from reactconst Geolocation ({ latitude, longitude }) (divdivLatitude: {latitude}/divdivLongitude: {longitude}/div/div
)Geolocation.propTypes {latitude: React.PropTypes.number,longitude: React.PropTypes.number,
}export default Geolocation定义UI容器
包装了UI组件同时所有的状态全在这里进行处理
import React from react
import Geolocation from ./geolocationclass GeolocationContainer extends React.Component {constructor(props) {super(props)this.state {latitude: null,longitude: null,}this.handleSuccess this.handleSuccess.bind(this)}handleSuccess({ coords }) {this.setState({latitude: coords.latitude,longitude: coords.longitude,})}render() {return ( //此处包装Geolocation {...this.state} /)}
}export default GeolocationContainer保持组件的纯粹
React 便围绕着这个概念进行设计。React 假设你编写的所有组件都是纯函数。也就是说对于相同的输入你所编写的 React 组件必须总是返回相同的 JSX。简单理解一下就是上面所说的UI和操作分离的情况。比如下面的例子
function Cup() {// Bad正在更改预先存在的变量最好把guest做为Cup的一个参数guest guest 1;return h2Tea cup for guest #{guest}/h2;
}export default function TeaSet() {return (Cup /Cup /Cup //);
}这种作法有助于
组件可以在不同的环境下运行 — 例如在服务器上由于它们针对相同的输入总是返回相同的结果因此一个组件可以满足多个用户请求。可以为那些输入未更改的组件来 跳过渲染以提高性能。这是安全的做法因为纯函数总是返回相同的结果所以可以安全地缓存它们。如果在渲染深层组件树的过程中某些数据发生了变化React 可以重新开始渲染而不会浪费时间完成过时的渲染。纯粹性使得它随时可以安全地停止计算。
组件渲染的时机
有两种原因会导致组件的渲染:
组件的 初次渲染。在进行初次渲染时, React 会调用根组件。组件或者其祖先之一的 状态发生了改变。对于后续的渲染, React 会调用内部状态更新触发了渲染的函数组件。
这个过程是递归的如果更新后的组件会返回某个另外的组件那么 React 接下来就会渲染 那个 组件而如果那个组件又返回了某个组件那么 React 接下来就会渲染 那个 组件以此类推。这个过程会持续下去直到没有更多的嵌套组件并且 React 确切知道哪些东西应该显示到屏幕上为止。
基于以上也是为什么要保持组件纯粹的原因了因为这关乎性能。
State详解
这东西到底干啥用的呢本质上React也是一个MVVM的实现核心是一个有状态的组件虽然可以通过传统的方式来实现数据改变时的UI样式但会比较麻烦所以React给每个组件加了一个state功能通过state来实现数据和展现的互动其原理简单理解如下 state 机制目的是代替原有的props机制实现数据和视图的绑定。setState()方法可接受一个Object参数内部会把此参数和原state数据进行合并。 setState()
语法格式setState({}, callBack)
一般在使用React开发组件时建议选择受控组件开发然后通过控制state进而控制render()方法的调用用这种方式来取代非受控组件的开发模式。
比如在下例中input 绑定一个 change 事件每当表单的状态发生变化时都会被写入到组件的 state 中这种组件在 React 中被称为受控组件(controlled component)。在受控组件中React 通过这种方式消除了组件的局部状态使得应用的整个状态更加可控 React 受控组件更新 state 的流程:
可以通过在初始 state 中设置表单的默认值。每当表单的值发生变化时调用 onChange 事件处理器。事件处理器通过合成事件对象 e 拿到改变后的状态并更新应用的 state。setState 触发视图的重新渲染完成表单组件值的更新。
class App extends React.Component {constructor(props) {super(props);this.handleInputChange this.handleInputChange.bind(this);this.state {inputVal: male, //默认值};}handleInputChange(e) {this.setState({inputVal: e.target.value,});}render() {const { inputVal} this.state;return (divinput typeradio valuemale checked{inputVal male} onChange{this.handleInputChange}//div);}}其底层原理是在 React 内部为每个组件保存了一个数组其中每一项都是一个 state 对。它维护当前 state 对的索引值在渲染之前将其设置为 “0”。每次调用 useState 时React 都会为你提供一个 state 对并增加索引值。