整理一下React中關於state和props的知識點。javascript
在任何應用中,數據都是必不可少的。咱們須要直接的改變頁面上一塊的區域來使得視圖的刷新,或者間接地改變其餘地方的數據。React的數據是自頂向下單向流動的,即從父組件到子組件中,組件的數據存儲在props
和state
中,這兩個屬性有啥子區別呢?html
React的核心思想就是組件化思想,頁面會被切分紅一些獨立的、可複用的組件。java
組件從概念上看就是一個函數,能夠接受一個參數做爲輸入值,這個參數就是props
,因此能夠把props
理解爲從外部傳入組件內部的數據。因爲React是單向數據流,因此props
基本上也就是從服父級組件向子組件傳遞的數據。react
假設咱們如今須要實現一個列表,根據React組件化思想,咱們能夠把列表中的行當作一個組件,也就是有這樣兩個組件:<ItemList/>
和<Item/>
。git
先看看<ItemList/>
github
import Item from "./item"; export default class ItemList extends React.Component{ const itemList = data.map(item => <Item item=item />); render(){ return ( {itemList} ) } }
列表的數據咱們就暫時先假設是放在一個data
變量中,而後經過map
函數返回一個每一項都是<Item item='數據'/>
的數組,也就是說這裏其實包含了data.length
個<Item/>
組件,數據經過在組件上自定義一個參數傳遞。固然,這裏想傳遞幾個自定義參數均可以。json
在<Item />
中是這樣的:數組
export default class Item extends React.Component{ render(){ return ( <li>{this.props.item}</li> ) } }
在render
函數中能夠看出,組件內部是使用this.props
來獲取傳遞到該組件的全部數據,它是一個對象,包含了全部你對這個組件的配置,如今只包含了一個item
屬性,因此經過this.props.item
來獲取便可。異步
props
常常被用做渲染組件和初始化狀態,當一個組件被實例化以後,它的props
是隻讀的,不可改變的。若是props
在渲染過程當中能夠被改變,會致使這個組件顯示的形態變得不可預測。只有經過父組件從新渲染的方式才能夠把新的props
傳入組件中。函數
在組件中,咱們最好爲props
中的參數設置一個defaultProps
,而且制定它的類型。好比,這樣:
Item.defaultProps = { item: 'Hello Props', }; Item.propTypes = { item: PropTypes.string, };
關於propTypes
,能夠聲明爲如下幾種類型:
optionalArray: PropTypes.array, optionalBool: PropTypes.bool, optionalFunc: PropTypes.func, optionalNumber: PropTypes.number, optionalObject: PropTypes.object, optionalString: PropTypes.string, optionalSymbol: PropTypes.symbol,
注意,bool
和func
是簡寫。
這些知識基礎數據類型,還有一些複雜的,附上連接:
https://facebook.github.io/react/docs/typechecking-with-proptypes.html
props
是一個從外部傳進組件的參數,主要做爲就是從父組件向子組件傳遞數據,它具備可讀性和不變性,只能經過外部組件主動傳入新的props
來從新渲染子組件,不然子組件的props
以及展示形式不會改變。
state
是什麼呢?
State is similar to props, but it is private and fully controlled by the component.
一個組件的顯示形態能夠由數據狀態和外部參數所決定,外部參數也就是props
,而數據狀態就是state
。
export default class ItemList extends React.Component{ constructor(){ super(); this.state = { itemList:'一些數據', } } render(){ return ( {this.state.itemList} ) } }
首先,在組件初始化的時候,經過this.state
給組件設定一個初始的state
,在第一次render
的時候就會用這個數據來渲染組件。
state
不一樣於props
的一點是,state
是能夠被改變的。不過,不能夠直接經過this.state=
的方式來修改,而須要經過this.setState()
方法來修改state
。
好比,咱們常常會經過異步操做來獲取數據,咱們須要在didMount
階段來執行異步操做:
componentDidMount(){ fetch('url') .then(response => response.json()) .then((data) => { this.setState({itemList:item}); } }
當數據獲取完成後,經過this.setState
來修改數據狀態。
當咱們調用this.setState
方法時,React會更新組件的數據狀態state
,而且從新調用render
方法,也就是會對組件進行從新渲染。
注意:經過this.state=
來初始化state
,使用this.setState
來修改state
,constructor
是惟一可以初始化的地方。
setState
接受一個對象或者函數做爲第一個參數,只須要傳入須要更新的部分便可,不須要傳入整個對象,好比:
export default class ItemList extends React.Component{ constructor(){ super(); this.state = { name:'axuebin', age:25, } } componentDidMount(){ this.setState({age:18}) } }
在執行完setState
以後的state
應該是{name:'axuebin',age:18}
。
setState
還能夠接受第二個參數,它是一個函數,會在setState
調用完成而且組件開始從新渲染時被調用,能夠用來監聽渲染是否完成:
this.setState({ name:'xb' },()=>console.log('setState finished'))
state
的主要做用是用於組件保存、控制以及修改本身的狀態,它只能在constructor
中初始化,它算是組件的私有屬性,不可經過外部訪問和修改,只能經過組件內部的this.setState
來修改,修改state
屬性會致使組件的從新渲染。
state
是組件本身管理數據,控制本身的狀態,可變;props
是外部傳入的數據參數,不可變;state
的叫作無狀態組件,有state
的叫作有狀態組件;props
,少用state
。也就是多寫無狀態組件。