上一篇文章,React入門 大體瞭解了, 如何基本的使用組件和更新組件. 如今,咱們來點新的~css
React針對於props 專門提供了兩種屬性驗證, 來保證組件的可複用性~ propTypes
和defaultProps
. propTypes用來設置屬性是否必須, 類型等. defaultProps就是用來設置屬性的默認值.node
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 reactreact
而且,在設置類型的同時,你還能夠在後面再寫上isRequired
這樣的內容.PropTypes.array.isRequired
.css3
還有一些其餘的內容, like:npm
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來闡述一下. 寫一個搜索框~babel
基本樣式爲:app
這個demo其實就一箇中心點,經過onChange事件來控制內容信息的展現. 信息的展現,就是經過觸發this.setState 方法來完成.
我這裏, 就不貼代碼了,直接放在online demo裏了.ide
所謂的生命週期,實際上就是一些列觸發或者不觸發渲染的方法~
而涉及到這些渲染觸發操做的, 大概就有4個過程:性能
Mounting動畫
Unmounting
Props Change
State Change
咱們來講一下,每一個過程對應狀態的觸發順序.
該過程表示渲染組件的過程. 簡而言之就是將咱們寫的組件類(class), 經過render 方法渲染到頁面上. 具體觸發順序是:
Class: 已經書寫好的UI 類
componentWillMount: 該方法會在render方法以前被invoke. 方法內部會設置好組件的state
render: 正式的觸發方法
componentDidMount: 將節點正式渲染到頁面上, 在該方法後面, 就能夠實際操做DOM.
卸載組件的過程. 即:
<div> <single></single> </div>
渲染爲:
<div> {/* single component has been removed*/} </div>
該過程實際上只會觸發一個方法:
componentWillUnmount: 在DOM即將刪除以前觸發該方法, 因此你能夠在該方法內部作一些事件的解綁
看名字你們差很少已經猜出來了. 該過程就是主要處理props 內容的改變. 基本的過程爲:
ComponentWillReciveProps: 當組件接收到新的props便會觸發該方法. 若是你在該方法內調用this.setState其實是沒有效果的.(Ps: 該方法其實並無什麼x用)
shouldComponentUpdate: 檢測是否組件須要從新渲染. 實際上就是經過該方法決定, render 方法是否能夠直接跳過
componentWillUpdate: 新的props和state會被接收. 而且在該方法內不能使用this.setState進行渲染(反正也無效)
render: 不解釋了
componentDidUpdate: 在DOM已經徹底渲染完成後,觸發.
狀態屬性的改變實際上和Props的流程差很少,只是是少了ComponentWillReciveProps
方法.即,流程爲:
shouldComponentUpdate: 檢測是否組件須要從新渲染. 實際上就是經過該方法決定, render 方法是否能夠直接跳過
componentWillUpdate: 新的props和state會被接收. 而且在該方法內不能使用this.setState進行渲染(反正也無效)
render: 不解釋了
componentDidUpdate: 在DOM已經徹底渲染完成後,觸發.
上面說了這麼多方法, 那這些方法究竟是寫在哪裏的呢?
~~ 只能寫在你的class UI中.
如今,咱們要在UI渲染完成時, 彈出一個提示框,說明完成。
so how to do?
很簡單.看一下代碼.
class Search extends Component{ render(){ return( <div> </div> ) } componentDidMount(){ alert('finish'); } }
這下, 應該懂了. 這裏大體瞭解一下就行, 當作鋪墊.
由於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 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個動畫狀態可供選擇:
Appear: 當第一次加載節點時,能夠進行的動畫.
transitionAppear: 表示是否開啓加載動畫. 默認狀況下是設置爲false. 因此,若是你要時候, 須要手動開啓transitionAppear={true}
. 開啓以後, 你就須要添加.name-appear
和name-appear-active
的class 動畫內容.
Enter: 當添加節點時,會觸發添加動畫.若是你使用的話,只須要設置.transitionEnterTimeout={timeout}
便可。
transitionEnterTimeout: 用來設置節點添加動畫持續的時間,不過, 你一樣須要在class 中設置相同的transition
時間. 若是時間不統一, 會以React設置爲主.和Appear同樣,也須要手動添加name-enter
類名
Leave: 刪除節點時, 觸發的動畫. 同上 enter. 須要手動添加transitionLeaveTimeout
這裏提一下, 關於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; } } }