react- 相关
生命周期方法
组件的生命周期分成三个状态:
- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
React 为每个状态都提供了两种处理函数,will
函数在进入状态之前调用,did
函数在进入状态之后调用,三种状态共计五种处理函数。
- componentWillMount()
- componentDidMount()
- componentWillUpdate(object nextProps, object nextState)
- componentDidUpdate(object prevProps, object prevState)
- componentWillUnmount()
此外,React 还提供两种特殊状态的处理函数。
- componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
- shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
挂载:componentWillMount
服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。如果在这个方法内调用 setState
,render()
将会感知到更新后的 state,将会执行仅一次,尽管 state 改变了
React.createClass({ componentWillMount() { ... } });
挂载: componentDidMount
在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。在生命周期中的这个时间点,组件拥有一个 DOM 展现,你可以通过 this.getDOMNode()
来获取相应 DOM 节点。如果想和其它 JavaScript 框架集成,使用 setTimeout
或者 setInterval
来设置定时器,或者发送 AJAX 请求,可以在该方法中执行这些操作。
React.createClass({ componentDidMount() { ... } });
移除: componentWillUnmount
在组件从 DOM 中移除的时候立刻被调用。在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount
中创建的 DOM 元素。
React.createClass({ componentWillUnmount() { ... } });
更新: componentWillReceiveProps
参数:object nextProps
在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。用此函数可以作为 react 在 prop 传入之后, render()
渲染之前更新 state 的机会。老的 props 可以通过 this.props
获取到。在该函数中调用 this.setState()
将不会引起第二次渲染。
React.createClass({ componentWillReceiveProps(nextProps) { this.setState({ }) } });
注意:对于 state,没有相似的方法,如果需要在 state 改变的时候执行一些操作,请使用 componentWillUpdate
。
更新: shouldComponentUpdate
返回:boolean;
参数1:object nextProps
参数2:object nextState
在接收到新的 props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用,在使用 forceUpdate
方法的时候也不会。如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false
。默认情况下,shouldComponentUpdate
总会返回 true
React.createClass({ shouldComponentUpdate(nextProps, nextState) { return false } }); 如果 shouldComponentUpdate返回false,则render()
将不会执行,直到下一次 state 改变。(另外,componentWillUpdate
和componentDidUpdate
也不会被调用。)
更新: componentWillUpdate
参数1:object nextProps
参数2:object nextState
在接收到新的 props 或者 state 之前立刻调用。在初始化渲染的时候该方法不会被调用。
React.createClass({ componentWillUpdate(nextProps, nextState) { ... } });
注意:你不能在刚方法中使用 this.setState()
。如果需要更新 state 来响应某个 prop 的改变,请使用 componentWillReceiveProps
。
更新: componentDidUpdate
参数1:object prevProps
参数2:object prevState
在组件的更新已经同步到 DOM 中之后立刻被调用。该方法不会在初始化渲染的时候调用。使用该方法可以在组件更新之后操作 DOM 元素。
React.createClass({ componentDidUpdate(nextProps, nextState) { ... } });
注意:为了兼容 v0.9,DOM 节点会作为最后一个参数传入。如果使用这个方法,你仍然可以使用 this.getDOMNode()
来访问 DOM 节点。
例子: 路由切换时,组件生命周期的变化情况
路由配置如下:
<Route path="/" component={App}> <IndexRoute component={Home}/> <Route path="invoices/:invoiceId" component={Invoice}/> <Route path="accounts/:accountId" component={Account}/> </Route>
1. 当用户打开应用的 '/' 页面
2. 当用户从 '/' 跳转到 '/invoice/123'
App
从 router 中接收到新的 props(例如children
、params
、location
等数据), 所以App
触发了componentWillReceiveProps
和componentDidUpdate
两个生命周期方法
Home
不再被渲染,所以它将被移除,触发 componentWillUnmount
Invoice
首次被挂载 触发 componentWillMount 和 componentDidMount
3. 当用户从 /invoice/123
跳转到 /invoice/789
- 所有的组件之前都已经被挂载, 所以只是从 router 更新了 props.
4. 当从 /invoice/789
跳转到 /accounts/123
组件的详细说明
getInitialState
在组件挂载之前调用一次。返回值将会作为 this.state
的初始值。
React.createClass({ getInitialState: function() { return {liked: false}; }, render: function() { ... } });
getDefaultProps
在组件类创建的时候调用一次,然后返回值被缓存下来。如果父组件没有指定 props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props
(使用 in
检测属性)。
该方法在任何实例创建之前调用,因此不能依赖于 this.props
。另外,getDefaultProps()
返回的任何复杂对象将会在实例间共享,而不是每个实例拥有一份拷贝。
React.createClass({ getDefaultProps: function() { return {liked: false}; }, render: function() { ... } });
propTypes
组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。
组件类的PropTypes
属性,就是用来验证组件实例的属性是否符合要求
React.createClass({ propTypes: { optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // 所有可以被渲染的对象:数字,字符串,DOM 元素或包含这些类型的数组。 optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 用 JS 的 instanceof 操作符声明 prop 为类的实例。 optionalMessage: React.PropTypes.instanceOf(Message), // 用 enum 来限制 prop 只接受指定的值。 optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), // 指定的多个对象类型中的一个 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // 指定类型组成的数组 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // 指定类型的属性构成的对象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // 特定形状参数的对象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), // 以后任意类型加上 `isRequired` 来使 prop 不可空。 requiredFunc: React.PropTypes.func.isRequired, // 不可空的任意类型 requiredAny: React.PropTypes.any.isRequired, // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。 customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } } });
单个子级
React.PropTypes.element
可以限定只能有一个子级传入。
var MyComponent = React.createClass({ propTypes: { children: React.PropTypes.element.isRequired }, render: function() { return ( <div> {this.props.children} // 有且仅有一个元素,否则会抛异常。 </div> ); } });
默认 Prop 值
var ComponentWithDefaultProps = React.createClass({ getDefaultProps: function() { return { value: 'default value' }; } });
当父级没有传入 props 时,getDefaultProps()
可以保证 this.props.value
有默认值,注意 getDefaultProps
的结果会被 缓存。得益于此,你可以直接使用 props,而不必写手动编写一些重复或无意义的代码
ref
组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref
属性
<input type="text" ref="myTextInput" />
this.refs.myTextInput.focus();
this.props.children
this.props
对象的属性与组件的属性一一对应,但是有一个例外,就是this.props.children
属性。它表示组件的所有子节点
mixins
组件是 React 里复用代码最佳方式,但是有时一些复杂的组件间也需要共用一些功能。React 使用 mixins
来解决这类问题。
一个通用的场景是:一个组件需要定期更新。用 setInterval()
做很容易,但当不需要它的时候取消定时器来节省内存是非常重要的。React 提供 生命周期方法 来告知组件创建或销毁的时间。下面来做一个简单的 mixin,使用 setInterval()
并保证在组件销毁时清理定时器。
var SetIntervalMixin = { componentWillMount: function() { this.intervals = []; }, setInterval: function() { this.intervals.push(setInterval.apply(null, arguments)); }, componentWillUnmount: function() { this.intervals.map(clearInterval); } }; var TickTock = React.createClass({ mixins: [SetIntervalMixin], // 引用 mixin getInitialState: function() { return {seconds: 0}; }, componentDidMount: function() { this.setInterval(this.tick, 1000); // 调用 mixin 的方法 }, tick: function() { this.setState({seconds: this.state.seconds + 1}); }, render: function() { return ( <p> React has been running for {this.state.seconds} seconds. </p> ); } }); React.render( <TickTock />, document.getElementById('example') );
关于 mixin 值得一提的优点是,如果一个组件使用了多个 mixin,并用有多个 mixin 定义了同样的生命周期方法(如:多个 mixin 都需要在组件销毁时做资源清理操作),所有这些生命周期方法都保证会被执行到。方法执行顺序是:首先按 mixin 引入顺序执行 mixin 里方法,最后执行组件内定义的方法。
statics
statics
对象允许你定义静态的方法,这些静态的方法可以在组件类上调用
var MyComponent = React.createClass({
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
},
render: function() {
}
});
MyComponent.customMethod('bar'); // true
顶层 API
React.createClass
创建一个组件类,并作出定义。组件实现了 render()
方法,该方法返回一个子级。该子级可能包含很深的子级结构。组件与标准原型类的不同之处在于,你不需要使用 new 来实例化。 组件是一种很方便的封装,可以(通过 new )为你创建后台实例。
React.createElement
创建并返回一个新的指定类型的 ReactElement
。type 参数可以是一个 html 标签名字字符串(例如,“div”,“span”,等等),或者是 ReactClass
(通过 React.createClass
创建的)。
React.createFactory
返回一个生成指定类型 ReactElements 的函数。比如 React.createElement
,type 参数可以是一个 html 标签名字字符串(例如,“div”,“span”,等等),或者是 ReactClass
。
React.render
渲染一个 ReactElement 到 DOM 中,放在 container
指定的 DOM 元素下,返回一个到该组件的引用。
如果 ReactElement 之前就被渲染到了 container
中,该函数将会更新此 ReactElement,仅改变需要改变的 DOM 节点以展示最新的 React 组件。
如果提供了可选的回调函数,则该函数将会在组件渲染或者更新之后调用。
React.unmountComponentAtNode
从 DOM 中移除已经挂载的 React 组件,清除相应的事件处理器和 state。如果在 container 内没有组件挂载,这个函数将什么都不做。如果组件成功移除,则返回 true
;如果没有组件被移除,则返回 false
。
React.renderToString
把组件渲染成原始的 HTML 字符串。该方法应该仅在服务器端使用。React 将会返回一个 HTML 字符串。你可以在服务器端用此方法生成 HTML,然后将这些标记发送给客户端,这样可以获得更快的页面加载速度,并且有利于搜索引擎抓取页面,方便做 SEO。
如果在一个节点上面调用 React.render()
,并且该节点已经有了服务器渲染的标记,React 将会维护该节点,并且仅绑定事件处理器,保证有一个高效的首屏加载体验。
React.renderToStaticMarkup
string renderToStaticMarkup(ReactElement element)
和 renderToString
类似,除了不创建额外的 DOM 属性,例如 data-react-id
,因为这些属性仅在 React 内部使用。如果你想用 React 做一个简单的静态页面生成器,这是很有用的,因为丢掉额外的属性能够节省很多字节。
React.isValidElement
boolean isValidElement(* object)
判断对象是否是一个 ReactElement。
React.DOM
React.DOM
运用 React.createElement
为 DOM 组件提供了方便的包装。该方式仅在未使用 JSX 的时候适用。例如,React.DOM.div(null, 'Hello World!')
。
React.PropTypes
React.PropTypes
包含了能与组件 propTypes
对象共用的类型,用于验证传入组件的 props。更多有关 propTypes
的信息,参考复用组件。
React.initializeTouchEvents
initializeTouchEvents(boolean shouldUseTouch)
配置 React 的事件系统,使 React 能处理移动设备的触摸( touch )事件。
React.Children
React.Children
为处理 this.props.children
这个封闭的数据结构提供了有用的工具。
React.Children.map
object React.Children.map(object children, function fn [, object context])
在每一个直接子级(包含在 children
参数中的)上调用 fn
函数,此函数中的 this
指向 上下文
。如果 children
是一个内嵌的对象或者数组,它将被遍历:不会传入容器对象到 fn
中。如果 children 参数是 null
或者 undefined
,那么返回 null
或者 undefined
而不是一个空对象。
React.Children.forEach
React.Children.forEach(object children, function fn [, object context])
类似于 React.Children.map()
,但是不返回对象。
React.Children.count
number React.Children.count(object children)
返回 children
当中的组件总数,和传递给 map
或者 forEach
的回调函数的调用次数一致。
React.Children.only
object React.Children.only(object children)
返回 children
中仅有的子级。否则抛出异常。
组件 API
setState
合并 nextState 和当前 state。这是在事件处理函数中和请求回调函数中触发 UI 更新的主要方法。另外,也支持可选的回调函数,该函数在 setState 执行完毕并且组件重新渲染完成之后调用
注意:
- 绝对不要直接改变
this.state
, setState()
不会立刻改变this.state
,而是创建一个即将处理的 state 转变。在调用该方法之后获取this.state
的值可能会得到现有的值,而不是最新设置的值。- 不保证
setState()
调用的同步性,为了提升性能,可能会批量执行 state 转变和 DOM 渲染。 setState()
将总是触发一次重绘,除非在shouldComponentUpdate()
中实现了条件渲染逻辑。如果使用可变的对象,但是又不能在shouldComponentUpdate()
中实现这种逻辑,仅在新 state 和之前的 state 存在差异的时候调用setState()
可以避免不必要的重新渲染。
- 绝对不要直接改变
replaceState
类似于 setState()
,但是删除之前所有已存在的 state 键,这些键都不在 nextState 中。
forceUpdate()
render()
方法从 this.props
或者 this.state
之外的地方读取数据,你需要通过调用 forceUpdate()
告诉 React 什么时候需要再次运行 render()
。如果直接改变了 this.state
,也需要调用 forceUpdate()
调用 forceUpdate()
将会导致 render()
方法在相应的组件上被调用,并且子级组件也会调用自己的 render()
,但是如果标记改变了,那么 React 仅会更新 DOM
getDOMNode
如果组件已经挂载到了 DOM 上,该方法返回相应的本地浏览器 DOM 元素。从 DOM 中读取值的时候,该方法很有用,比如获取表单字段的值和做一些 DOM 操作。当 render
返回 null
或者 false
的时候,this.getDOMNode()
返回 null
。
isMounted
如果组件渲染到了 DOM 中,isMounted()
返回 true。可以使用该方法保证 setState()
和 forceUpdate()
在异步场景下的调用不会出错
setProps
调用 setProps()
来改变组件的属性,触发一次重新渲染。另外,可以传递一个可选的回调函数,该函数将会在 setProps
完成并且组件重新渲染完成之后调用
注意:
刚方法仅在根组件上面调用。也就是说,仅在直接传给 React.render()
的组件上可用,在它的子级组件上不可用。如果你倾向于在子组件上使用 setProps()
,不要利用响应式更新,而是当子组件在 render()
中创建的时候传入新的 prop 到子组件中。
replaceProps
类似于 setProps()
,但是删除所有已存在的 props,而不是合并新旧两个 props 对象
react- 相关的更多相关文章
- 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux
因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...
- React相关知识和经验的碎片化记录
React相关知识和经验的碎片化记录 1.Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a chil ...
- 常用的package.json以及React相关
常用的package.json以及React相关 前言 package.json 的简单介绍 简单版的 package.json 必备属性(name & version) name 字段 ve ...
- react相关知识点
1.react内联样式写法: <div style={{width:'200px',height:'100px',border:'1px solid red'}}> </div> ...
- react相关
react 简单入门 ant 蚂蚁金服react组件 redux 阮一峰入门react material-ui组件库 webpack入门 http://www.jianshu.com/p/42e115 ...
- REACT相关资料合集
===实例=== https://github.com/jesseskinner/react-webpack-demo ===UI组件库=== https://github.com/amazeui/a ...
- React相关:npm,ES6,
1.NPM: 参考:npm使用入门 npm 学习笔记整理 2.ES6参考:ES6 let命令:ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块 ...
- 记录一次react相关总结
背景说明:元旦接到一个管理后台的项目,是一个关于自定义专题的项目.通过后台的配置自定义专题,前端根据专题模块进行渲染数据.由于管理后台是react做的前后分离,对于一个后端的我来说写写js也算是浅尝一 ...
- react相关知识点链接整理
1.React组件之间的通信 2.中间件做代理解决跨域问题 3.不要再问我跨域的问题了 4.React 组件数据流 && 组件间沟通 5.如何理解虚拟DOM 6.react性能调谐与d ...
- react相关小技巧
一.我们在项目中切换路由的时候可能会遇到 Warning: setState(...): Can only update a mounted or mounting component. This u ...
随机推荐
- uoj#450. 【集训队作业2018】复读机(单位根反演)
题面 传送门 题解 我的生成函数和单位根反演的芝士都一塌糊涂啊-- \(d=1\),答案就是\(k^n\)(因为这里\(k\)个复读机互不相同,就是说有标号) \(d=2\),我们考虑复读机的生成函数 ...
- POI生成Excel强制换行
自动换行的设置: HSSFCellStyle cellStyle=workbook.createCellStyle(); cellStyle.setWrapText(true); cell.setCe ...
- 2019-5-1 maven学习笔记
一.maven的好处 同样的项目使用maven工程来实现,由于不需要导入很多jar包,源码很小 原理:根据坐标到项目的仓库里查找需要的依赖 二.安装步骤 1.到http://maven.apache. ...
- Functions that return a function
javascript学习中,经常会遇到闭包的问题,然后闭包的很多例子中又会遇到很多返回函数的闭包的例子程序.因为对闭包的理解还不够透彻,然后对于Functions rerurn a function产 ...
- P2925 [USACO08DEC]干草出售Hay For Sale
传送门 把每体积的干草价值看成一,就变成求最大价值 直接上背包就行了 注意优化常数 #include<iostream> #include<cstdio> #include&l ...
- 权限知识中的AIX ACL
Aix ACL是对标准权限位的扩展.通过修改分配给个人或组的标准权限,对每个文件或目录进行更精细的控制. 对每个组或用户,有3种权限分配情况: PERMIT : 准许对文件或目录的特定权限. DEMY ...
- A. The number of positions
A. The number of positions time limit per test 0.5 second memory limit per test 256 megabytes input ...
- vue父子组件通信(prop)
先定义子组件,注册prop接收父组件传递的值 <template> <div> <div>{{message}}(子组件)</div> </div ...
- 用NaviCat创建存储过程批量添加测试数据
打开navicat连接上数据库,然后打开左上角函数,新建一个函数. BEGIN DECLARE i int; --声明变量 DECLARE groupid int; set i=LAST_INSERT ...
- JavaSE---线程同步
1.当多个线程同时访问同一个数据时,容易出现线程安全问题,必须进行线程同步: 2.解决方案: 1.1 Java的多线程引入了 同步监视器 ,使用同步监视器的通用方法就是 同步代码块 //线程开始 ...