工作或者面試中經(jīng)常遇到這樣的問題,“子組件如何向父組件傳值?”。其實很簡單,概括起來就是:react中state改變了,組件才會update。父寫好state和處理該state的函數(shù),同時將函數(shù)名通過props屬性值的形式傳入子,子調用父的函數(shù),同時引起state變化,子組件要寫在父組件之前。
很簡單的一個例子,我們在輸入框中輸入溫度,輸入框下面顯示冷和熱。這里就有兩個組件,輸入框和它下面的顯示內容,且它們共享一個狀態(tài),就是溫度。所以我們要把溫度這個狀態(tài)放到這兩個組件的父組件中。這里就有三個組件,一個輸入框 TemperatureInput,一個是顯示內容 TemperatureShow,父組件 TemperatureContainer。 由于 TemperatuerInput 和TemperatureShow 是無狀態(tài)的,可以用函數(shù)式聲明,接受父組件傳來的 props. TempeartureContainer 是有狀態(tài)的,要用class聲明。
TemperatureShow 組件非常簡單,就是條件渲染。根據(jù)父組件傳遞過來的溫度,渲染出不同的內容。
//final TemperatureShow Class
class TemperatureShow extends React.Component{
constructor(props){
super(props);
}
render(){
if(this.props.temperature >38) {
return <p>溫度:<span style={{color:'#f50',fontSize:'18px'}}>熱</span></p>
}else if(this.props.temperature<=38 && this.props.temperature >=0){
return <p>溫度:<span style={{color:'#0098f4'}}>正合適</span></p>
}else {
return <p>溫度:<span style={{color:'#333'}}>冷</span></p>
}
}
}
TemperatureInput 則包含一個input輸入框,在react,輸入框主要通過 value 和 onChange 事件進行控制,狀態(tài)是自保持的。但是這里我們把狀態(tài)放到父組件 TempeartureContainer 中,輸入框是無狀態(tài)的,所以它的value值也只能從父組件中獲取,onChange 事件也只把用戶輸入的值傳遞給父組件,這里就是父子之間相互通信。 這里先簡單寫一個它的表現(xiàn),onChange 稍后再說。
//TemperatureInput Class
class TemperatureInput extends React.Component{
constructor(props){
super(props);
}
render(){
return(
<p>
<label htmlFor="tempInput">請輸入天氣溫度:</label>
{/* onChange 事件調用函數(shù)*/}
<input className="Tem-input" type="text" name="tempInput" value={this.props.temperature} onChange={}/>
</p>
);
}
}
還剩下 TempeartureContainer 父組件,它是一個容器,把所有的組件包起來,當然,它還要定義狀態(tài)temperature,傳遞給子組件。
//TemperatureContainer Class
class TemperatureContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
temperature: ''
};
}
render() {
let temperature = this.state.temperature;
return (
<div>
<TemperatureInput temperature={temperature}/>
<TemperatureShow temperature={parseFloat(temperature) } />
</div>
)
}
}
現(xiàn)在通過ReactDOM.render 把TempeartureContainer 渲染到頁面上。
ReactDOM.render(
<TemperatureContainer />,
document.getElementById('root')
);
最后我們要處理一下input 輸入框中的輸入問題,當我們進行輸入的時候,會觸發(fā)onChange事件,這時要改變temperature 的值,但是input自身是無法做到的,因為temperature存在于 父組件中,只能在父組件中改變。父組件中也很容易做到,聲明一個函數(shù),調用setState 方法,在setState中我們把新值賦值給temperature,但是這個新值,也就是用戶輸入的值,有點問題,它存在于子組件input 中, 其實也很好解決,函數(shù)可以進行傳參,函數(shù)通過傳參可以獲得它想要的值。所以在父組件中聲明函數(shù),在子組件調用,子組件通過函數(shù)傳參,把獲得的新值傳遞給這個函數(shù),那么父組件 也就獲得了子組件的值,當然父組件中函數(shù)要有一個參數(shù)用于接收值。父組件中聲明的函數(shù),子組件怎么調用? 這更簡單了,父組件可以通過props 傳遞給子組件。
在父組件中聲明一個函數(shù),它要有一個參數(shù),同時通過props 傳遞給子組件。
//final TemperatureContainer Class
class TemperatureContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
temperature: ''
};
}
// 父組件中的函數(shù),接受一個參數(shù)
handleTemp = (temperature) => {
this.setState({
temperature:temperature
})
};
render() {
let temperature = this.state.temperature;
return (
<div>
{/* 傳遞給子組件*/}
<TemperatureInput temperature={temperature} onTemperateChange={this.handleTemp}/>
<TemperatureShow temperature={parseFloat(temperature) } />
</div>
)
}
}
export default TemperatureContainer;
子組件調用父組個傳遞過來的參數(shù),并進行傳值。
//final TemperatureInput Class
class TemperatureInput extends React.Component{
constructor(props){
super(props);
}
handleTemp = (e) =>{
// 接受父組件傳遞過來的函數(shù),調用并傳值給父組件
this.props.onTemperateChange(e.target.value)
};
render(){
return(
<p>
<label htmlFor="tempInput">請輸入天氣溫度:</label>
{/* onChange 事件調用函數(shù)*/}
<input className="Tem-input" type="text" name="tempInput" value={this.props.temperature} onChange={this.handleTemp}/>
</p>
);
}
}
參考地址:父子組件之間的通信