[英]React component with ajax call - life-cycle
因此,我有一个有趣的案例,它与Ajax调用一起使用react。
在上下文中,我有一个带有3个标签的手风琴。 初始化Accordion react组件后,我首先打开了第一个选项卡,其余的则关闭了。 每个选项卡的主体中都有一个所谓的DictionaryCall组件,它看起来像这样:
return class DictionaryCall extends React.Component {
constructor (props) {
super();
this.state = {
word: '',
data: [],
error: false,
nodata: false,
initialLoaded: props.load
}
}
componentDidMount () {
if(this.state.initialLoaded){
this.callAjax();
}
}
componentWillReceiveProps (nextProps) {
if(nextProps.load){
this.setState({initialLoaded: true});
this.callAjax();
}
}
callAjax () {
$.ajax({
url: this.props.url,
dataType: 'json',
catche: false,
method: 'POST',
data: {word: this.props.word},
success: function(data){
if(!data.length){
this.setState({nodata: true});
} else {
this.setState({data: data});
}
}.bind(this),
error: function(xhr, status, error){
console.log(this.props.url, status, error.toString());
this.setState({error: true});
}.bind(this)
});
}
render () {
let body,
error = this.state.error;
if(this.state.nodata){
body = <div>No definition found</div>
} else {
body = <DataTab data={this.state.data} title={this.props.word}/>
}
return (
<div className="dictionary-call">
{body}
{error ? <ServerError onClick={this.callAjax.bind(this)}/> : null}
</div>
)
}
};
根据React docs用props设置初始状态的所有拳头都是反模式,除非您明确指定仅用于组件初始化。
因此,在构造函数中可以看到,我正在使用props.load
设置initialLoaded
状态。 我将props.load
作为true
传递给第一个“手风琴”选项卡,因为我希望它首先被加载。
调用componentDidMount
方法并检查initialLoaded
状态。 如果将其设置为true
则只需调用ajax并重新渲染该组件。
现在比较棘手。 componentWillReceiveProps
方法。 我希望,当用户单击“手风琴”选项卡将其打开时,该组件将收到nextProps.load
。 然后将props.load
以true
值传递到组件。
我的问题是, componentWillReceiveProps
是调用this.callAjax()
的好地方吗? 在这种情况下,创建initalLoaded
状态似乎没有意义。 我不应该只是基于props.load
而是调用shouldComponentUpdate
吗?
或者,也许我应该坚持initalLoaded
状态并使用componentWillUpdate
或componentDidUpdate
。
请记住,当第一次打开手风琴标签时,我只想调用一次ajax调用。
谢谢!
因此,经过一番研究,我想回答我自己的问题。 希望它可以帮助某人。
解决方案非常简单干净(我认为)。
componentDidMount () {
if(this.state.initialLoaded){
this.callAjax();
}
}
componentWillReceiveProps (nextProps) {
if(nextProps.load){
this.setState({initialLoaded: true});
}
}
componentWillUpdate (nextProps, nextState) {
if(this.state.initialLoaded !== nextState.initialLoaded) {
this.callAjax();
}
}
此代码适用于组件的所有实例,无论它是第一个手风琴选项卡的子项(最初是打开的)还是其余选项卡的子项(最初是关闭的)。
在componentDidMount
方法中,我正在检查组件是否应该进行Ajax调用。 如果在初始化期间this.props.open
将this.state.initialLoaded
状态设置为true,则将进行ajax调用。 否则当然不会。
现在,当用户单击其他选项卡时,组件将在componentWillReceiveProps
期待道具。 在这里,仅当nextProps.load
为true时才设置状态,因为我想仅在load
字段为true时才可能加载数据。
最后,如果componentWillReceiveProps
的条件已满足,我正在检查this.state.initialLoaded
是否已更改。 因为只有在nextProp.load
为true时才可以更改它,所以它可以防止调用Ajax请求太多次(状态从true变为false时)。
这样,仅在第一次打开选项卡或最初打开选项卡时,我才调用Ajax请求。
这么简单!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.