簡體   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