[英]React - Child not getting Parent state
我的孩子組件:
class AddressList extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
console.log(this.props.state)
this.setState({
addresses: this.props.addresses
})
}
render() {
return (
<div>
<p>
<i className="text-muted">Adresses</i>
<span className="float-right"><i className="fa fa-plus-circle" onClick={this.toggleAddNewAddress.bind(this)}></i></span>
</p>
{this.state.addresses ? this.state.addresses.map((item, key) => {
return (
<span onClick={this.handleAddressClick.bind(this, item)} key={key} style={{"color": "#444D58", "marginRight": "1em"}}>
{item.formatted_address}
</span>
)
}) : <i>Loading Addresses...</i>}
</div>
);
}
}
export default AddressList;
我的父母組件:
class AddressList extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
axios({
url,
method: 'get',
headers
}).then((response) => {
this.setState({
data: response.data
})
})
}
render() {
return (
<div>
<AddressList addresses={this.state.data.addresses}/>
</div>
);
}
}
export default AddressList;
子組件不接收父state.data。 我認為這與組件生命周期有關。 孩子的componentDidMount是否在父母的componentWillMount之前被調用?
如何解決?
不,父級的componentWillMount
將在子級的componentDidMount
之前調用。 為確保將數據成功發送給子級,您應該在父componentDidMount
而不是componentWillMount
進行axios查詢。 提取數據並設置狀態后,它將重新呈現父級並將提取的數據發送給子級。
在您的代碼中,孩子的道具正在監聽父母的狀態。 問題是道具期望一個值傳遞給子代,而該子代在返回您的調用之前在您的狀態中不存在。 嘗試為要傳遞的對象設置默認狀態。 下面的例子。
不應將調用放在componentDidMount函數中,因為如果不添加條件,將會發出許多不必要的請求,並且響應和渲染之間的延遲會更大。 在每次重新渲染期間都會調用componentDidMount。
class AddressList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {
addresses: []
},
shouldMakeRequest: true
};
}
componentWillMount() {
if(this.state.shouldMakeRequest){
axios({
url,
method: 'get',
headers
}).then((response) => {
this.setState({
data: response.data
})
});
this.setState({shouldMakeRequest: false});
}
}
render() {
return (
<div>
<AddressList addresses={this.state.data.addresses}/>
</div>
);
}
}
export default AddressList;
您的代碼有很多錯誤。 因此,我已經很好地重寫了您的代碼。
誤區
變化
更改了下面的代碼。
// Address - parent component
class Address extends React.Component {
constructor(props) {
super(props);
this.state = {
addresses: null
};
}
render() {
return (
<div>
<AddressList addresses={this.state.data.addresses}/>
</div>
);
}
componentDidMount() {
let config = {
method: 'GET',
headers: headers
}
fetch(url, config).then(response=>{
response.json().then(res=>{
console.log(res);
this.setState({
addresses: res.data
})
})
})
}
}
export default Address;
// AddressList - child component
let AddressList = (props)=>{
let { addresses } = this.props;
return (
<div>
<p>
<i className="text-muted">Adresses</i>
<span className="float-right"><i className="fa fa-plus-circle" onClick={this.toggleAddNewAddress.bind(this)}></i></span>
</p>
{
addresses ? addresses.map((address, key) => {
return (
<span onClick={this.handleAddressClick.bind(this, address)} key={key} style={{"color": "#444D58", "marginRight": "1em"}}>
{address.formatted_address}
</span>
)
}) : <i>Loading Addresses...</i>
}
</div>
);
}
export default AddressList;
componentWillMount在組件的第一個渲染之前被調用,因此乍一看它似乎是放置數據獲取邏輯的理想場所。
但是,有一個“陷阱”:在呈現發生之前,異步調用將不會返回數據。 這意味着組件將使用空數據至少渲染一次。 無法“暫停”渲染以等待數據到達。 您不能以某種方式從componentWillMount返回諾言或在setTimeout中爭執。 處理此問題的正確方法是設置組件的初始狀態,以使其對渲染有效。
到componentDidMount被調用時,該組件已被渲染一次。
實際上,基於兩個原因,componentDidMount是發出調用以獲取數據的最佳位置 :
使用DidMount可以清楚地表明,只有在初始渲染之后才會加載數據。 這提醒您正確設置初始狀態,因此您不會因未定義狀態而導致錯誤。
如果您需要在服務器上渲染應用程序,則componentWillMount實際上將被調用兩次-一次在服務器上,再一次在客戶端上-這可能不是您想要的。 將數據加載代碼放入componentDidMount中將確保僅從客戶端獲取數據。
歸功於Dave Ceddia的職位
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.