繁体   English   中英

使用Ajax调用React组件-生命周期

[英]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.loadtrue值传递到组件。

我的问题是, componentWillReceiveProps是调用this.callAjax()的好地方吗? 在这种情况下,创建initalLoaded状态似乎没有意义。 我不应该只是基于props.load而是调用shouldComponentUpdate吗?

或者,也许我应该坚持initalLoaded状态并使用componentWillUpdatecomponentDidUpdate

请记住,当第一次打开手风琴标签时,我只想调用一次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.openthis.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM