上一篇文章,React入门 大致了解了,如何基本的使用组件和更新组件. 现在,我们来点新的~
属性验证
React针对于props 专门提供了两种属性验证,来保证组件的可复用性~ propTypes
和defaultProps
. propTypes用来设置属性是否必须,类型等. defaultProps就是用来设置属性的默认值.
class Search extends Component { constructor(){ super(); this.number = 0; } render() { return( <div> <span>{this.props.children}</span> </div> ) } } Search.propTypes = { children:PropTypes.string.isrequired } Search.defaultProps={ children:"default value" }
这里,设置this.children属性是必须的,并且如果你不写的话,他就会使用默认值,default value
来替代. online demo
ok,我们来看一下,React提供了哪几种PropType value.
from pro react
并且,在设置类型的同时,你还可以在后面再写上isrequired
这样的内容.PropTypes.array.isrequired
.
还有一些其他的内容,like:
proptype | desc |
---|---|
oneOfType | 可以用来设置多种类型.PropTypes.oneOfType([PropTypes.string,PropTypes.number]) |
node | 必须是能够渲染的类型,比如:numbers,strings,elements,or an array. |
oneOf | 只能是其中的某一个PropTypes.oneOf(['News','Photos']) |
怎么写组件?
怎么写组件这个问题,翻译一下就是,怎么使用state和props属性. 因为组件的render和state
以及props是息息相关的~
比较好的实践是,state归父UI管,props归子UI管. 这里,我们用一个简单的demo来阐述一下. 写一个搜索框~
基本样式为:
这个demo其实就一个中心点,通过onChange事件来控制内容信息的展示. 信息的展示,就是通过触发this.setState 方法来完成.
我这里,就不贴代码了,直接放在online demo里了.
组件的生命周期
所谓的生命周期,实际上就是一些列触发或者不触发渲染的方法~
而涉及到这些渲染触发操作的,大概就有4个过程:
Mounting
Unmounting
Props Change
State Change
我们来说一下,每个过程对应状态的触发顺序.
Mounting
该过程表示渲染组件的过程. 简而言之就是将我们写的组件类(class),通过render 方法渲染到页面上. 具体触发顺序是:
Unmounting
卸载组件的过程. 即:
<div> <single></single> </div>
渲染为:
<div> {/* single component has been removed*/} </div>
该过程实际上只会触发一个方法:
Props Change
看名字大家差不多已经猜出来了. 该过程就是主要处理props 内容的改变. 基本的过程为:
ComponentWillReciveProps: 当组件接收到新的props便会触发该方法. 如果你在该方法内调用this.setState实际上是没有效果的.(Ps: 该方法其实并没有什么x用)
shouldComponentUpdate: 检测是否组件需要重新渲染. 实际上就是通过该方法决定,render 方法是否可以直接跳过
componentWillUpdate: 新的props和state会被接收. 并且在该方法内不能使用this.setState进行渲染(反正也无效)
render: 不解释了
componentDidUpdate: 在DOM已经完全渲染完成后,触发.
State Changes
状态属性的改变实际上和Props的流程差不多,只是是少了ComponentWillReciveProps
方法.即,流程为:
shouldComponentUpdate: 检测是否组件需要重新渲染. 实际上就是通过该方法决定,触发.
lifecycle有什么用
上面说了这么多方法,那这些方法到底是写在哪里的呢?
~~ 只能写在你的class UI中.
现在,我们要在UI渲染完成时,弹出一个提示框,说明完成。
so how to do?
很简单.看一下代码.
class Search extends Component{ render(){ return( <div> </div> ) } componentDidMount(){ alert('finish'); } }
这下,应该懂了. 这里大致了解一下就行,当做铺垫.
immutable state
因为state是起到组件渲染的关键作用. 所以,一般外部的data都是存储在state当中, 而这样方式,即容易让你情不自禁的改动this.state中的属性. 这样很容易,造成你直接改动this.state状态会无效,以及会降低React内部对状态渲染的性能.
所以,建议就是,如果需要改动,请直接全部替换掉.
如果涉及到Object,则可以使用Object.assign 或者 filter,map等方法 copy一份.
let newObj = Object.assign({},this.state.male,this.state.female); let newArray = this.state.people.map((val)=>val);
不过,由于Object.assign支持度较低. 你可以自己手动造一个轮子.
Object.prototype.assign=function(origin,target){ for(var i in target){ if(origin.hasOwnProperty(i)){ origin[i]=target[i]; } } }
或者可以使用import "babel-polyfill"
来做替代. 不过,这还有一个问题,就是深浅copy. 这里稍微提供点clue. 可以使用 babel-polyfill
中的update
方法,该方法可以像mongoDB一样,将更新过后的Object,deeply copy 一份给你. 这里就不赘述了,到时候google 一下即差不多了.
动画React
React为了方便动画开发,特地提出了React CSSTransitionGroup这个addon. 细致点来说,CSSTransitionGroup 只提供了3个效果-渲染,新增,删除. 而且每个特效归根结底,还是需要你自己手动定义className,他只是把className 的替换帮你做了.
so,怎么用?
首先得下载npm:
npm install --save react-addons-css-transition-group // 在js中引用 import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
先看一个简单的demo. 这里也有线上demo:online demo
render(){ let lis = this.state.num.map((i,index)=>( <li key={i} onClick={this.remove.bind(this,index)} >{i}</li> )); return( <ul> <CSSGroup transitionName="demo" transitionEnterTimeout={300} transitionLeaveTimeout={300}> {lis} </CSSGroup> </ul> ) }
讲真,React会在真正渲染的时候,在他应用的位置添加span
元素 然后进行class的替换. 当然,如果涉及到更加复杂的动画,就需要使用css3提供的transitionend
和animationend
来进行设置.
React一共提供了4个动画状态可供选择:
这里提一下,关于React class Name的设置位置. 只要和渲染节点设置在一起即可.
比如,上面的demo,我的scss就可以设置为:
li { font-size: 15px; line-height: 24px; list-style-position: inside; list-style-type: disc; text-align: left; width: 80%; border: 1px solid; margin-top: 8px; &.demo-leave { opacity: 1; transform: translateX(0); &.demo-leave-active { opacity: 0; transform: translateX(250px); transition: 0.3s; } } }