[英]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.