React基礎篇(2) -- state&props&refs
內容簡介
- state
- props
- refs
- 行內樣式及動態類名
state
基本介紹
React 把元件看成是一個狀態機(State Machines)。通過與使用者的互動,實現不同狀態,然後渲染 UI,讓使用者介面和資料保持一致。
React 裡,只需更新元件的 state,然後根據新的 state 重新渲染使用者介面(不要操作 DOM)。
初始化狀態:
constructor() { super() this.state = { stateName1 : stateValue1, stateName2 : stateValue2 } }
讀取顯示:
this.state.stateName1
更新狀態-->更新介面 :
this.setState({stateName1 : newValue})
舉例如下:
class Myconponent1 extends React.Component{ constructor(props){ super(props) // 1、初始化狀態 this.state = { isLike:false } //將新增的方法中的this強制繫結為元件物件 this.fun = this.fun.bind(this) } //新新增方法:內部this預設undefined fun(){ //得到原有的狀態 let flag = !this.state.isLike // 3、更新狀態(因為是單向資料流,只能通過指定方式改變狀態) this.setState({ isLike:flag }) } render(){ // 2、讀取狀態 const {isLike}=this.state; return <h1 onClick={this.fun}>{isLike?'you like me?':'i like you!'}</h1> //可以直接這樣寫,但效率低 return <h1 onClick={this.fun.bind(this)}>{flag?'you like me?':'i like you!'}</h1> } }
理解上面後可簡化寫法:
class Myconponent1 extends React.Component{ state = { isLike:false } fun=()=>{ let {isLike}=this.state; this.setState({ isLike:!isLike }) } render(){ const {isLike}=this.state; return <h1 onClick={this.fun}>{isLike?'you like me?':'i like you!'}</h1> } }
注意
狀態更新可能是非同步的,不應該依靠它們的值來計算下一個狀態。
可使用第二種形式的 setState() 來接受一個函式而不是一個物件。
該函式將接收先前的狀態作為第一個引數,將此次更新被應用時的props做為第二個引數
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
props
基本介紹
state 和 props 主要的區別在於 props 是不可變的,而 state 可以根據與使用者互動來改變。這就是為什麼有些容器元件需要定義 state 來更新和修改資料。 而子元件只能通過 props 來傳遞資料(包括函式方法)。
props
是所有元件標籤的屬性的集合物件。
作用
:給標籤指定屬性, 從目標元件外部向元件內部傳遞資料(可能是一個function)。
在元件內部讀取屬性
: this.props.propertyName
擴充套件屬性: 將物件的所有屬性通過props傳遞
<Person {...person}/>
預設 Props
你可以通過元件類的 defaultProps 屬性為 props 設定預設值,例項如下:
class Hello extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
Hello.defaultProps = {
name: 'adoctors'
};
Props 驗證
Props 驗證使用 propTypes,它可以保證我們的應用元件被正確使用,React.PropTypes 提供很多驗證器 (validator) 來驗證傳入資料是否有效。當向 props 傳入無效資料時,JavaScript 控制檯會丟擲警告。
相關連結:http://npm.taobao.org/package/prop-types
子元件響應父元件變化
componentWillReceiveProps(newVal){
console.log("newVal",newVal)
}
舉例如下:
function Persion(props){
return (
<ul>
<li>姓名:{props.name}</li>
<li>年齡:{props.age}</li>
<li>性別:{props.sex}</li>
</ul>
)
}
// 預設屬性值
Persion.defaultProps={
name:"tom",
age:18,
sex:"男"
}
//對屬性值的型別和必要性限制,需要引入新檔案
Persion.propTypes={
name:PropTypes.string.isRequired, //string且必須有
age:PropTypes.number //number可以沒有
}
let msg={
name:"adoctors",
age:15,
sex:"男"
}
ReactDOM.render(<Persion {...msg}/>,document.getElementById(('com')))
//只傳name,可以直接寫則型別為string,若用{}包裹則可以傳成number
ReactDOM.render(<Persion name="jack" age={28} />,document.getElementById(('com1')))
refs
React 支援一種非常特殊的屬性 Ref ,你可以用來繫結到 render() 輸出的任何元件上。
這個特殊的屬性允許你引用 render() 返回的相應的支撐例項( backing instance )。這樣就可以確保在任何時間總是拿到正確的例項。
下面是幾個適合使用 refs 的情況:
- 處理焦點、文字選擇或媒體控制。
- 觸發強制動畫。
- 整合第三方 DOM 庫
如果可以通過宣告式實現,則儘量避免使用 refs。
不能在函式式元件上使用 ref 屬性,因為它們沒有例項。
//指定ref
<div ref="myDiv" style={{color:"red"}}>adoctors</div>
<input type="text" ref="ipt0"/>
<input type="text" ref={val=>this.ipt1=val}/>
<input type="text" onBlur={this.getVal}/>
//獲取相應的值
getVal=(e)=>{
console.log('獲取其他元素的(myDiv)的樣式: ',this.refs.myDiv.style.color);
console.log('獲取其他元素的(ipt0)值: ',this.refs.ipt0.value)
console.log('獲取其他元素的(ipt1)值: ',this.ipt1.value)
console.log('獲取本元素的值: ', e.target.value);
}
結果如圖:
行內樣式
變數控制
let flag={
display:this.props.list.length?'none':'block'
}
<div style={flag}>暫無評論</div>
行內單個樣式
<div style={{display: this.props.list.length ? "block" : "none"}}>此標籤是否隱藏</div>
行內多個樣式
<div style={{display: (index===this.state.currentIndex) ? "block" : "none", color:"red"}}>此標籤是否隱藏</div>
動態類名
1、標籤中沒有其他class,只需要動態新增一個.active的className,來顯示內容是否被選中狀態,則:
<div className={index===this.state.currentIndex?"active":null}>此標籤是否選中</div>
2、如果標籤本身有其他class,又要動態新增一個.active的className,來顯示內容是否被選中狀態,則:
<div className={["container tab", index===this.state.currentIndex?"active":null].join(' ')}>此標籤是否選中</div>
注意空格
或者,使用ES6寫法(推薦使用ES6寫法):
<div className={`container tab ${index===this.state.currentIndex?"active":null}`}>此標籤是否選中</div>