Search code examples
javascriptreactjsextreact

Managing React component behavior during update


I'm new to ReactJs, and working with the ExtReact framework. I'm displaying a grid, and made a pagination, which is working fine.

I customed the spinner displayed when datas are loading, and it works fine when the "component did mount".

But, when I update the component (like when I switch the page using the ExtReact paginator plugin), there is another native spinner displayed, and I want to custom it too.

My problem is that I don't find a proper way to do it with lifeCycle components methods, since the componentWillUpdate method is deprecated.

I first had only one 'isLoading' state, but I added 'isUpdating' since 'isLoading' was modified after the first render because of the way the store data are loaded.

The isUpdating state seems to stay false, this is what is displayed by the console:

Snapshot Is updating:false Updated! Is updating:false Saul Goodman!

Here is my Component code:

    import React, {Component} from 'react';
import {Grid, Column, Toolbar, SearchField} from '@sencha/ext-modern';
import {withRouter} from "react-router-dom";
import Spinner from '../../resources/components/Spinner';

Ext.require('Ext.grid.plugin.PagingToolbar');

class Subscriptions extends Component {

    state = {
        isLoading: true,
    };

    store = Ext.create('Ext.data.Store', {
        fields: ['Field1', 'Field2', 'Field3'],
        autoLoad: false,
        pageSize: 30,
        proxy: {
            type: 'rest', // refers to the alias "proxy.ajax" on Ext.data.proxy.Ajax
            url: 'niceadress',
            reader: {
                type: 'json'
            }
        }
    });

    /**
     * Loading the datas into the store and then removes the spinner when fetched successfully
     */
    componentDidMount() {
        this.store.load({
            callback: function (records, operation, success) {
                this.setState({
                    isLoading: (!success),
                });
                console.log("Saul Goodman!");
            },
            scope: this
        });
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        if (nextState.isLoading === true){
            return false;
        } else {
            return true;
        }
    };

    getSnapshotBeforeUpdate(prevProps, prevState) {
        this.setState({
            isLoading: true,
        });
        console.log('Snapshot');
        console.log('Is loading:' + this.state.isLoading)
        return prevState;
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        this.setState({
            isLoading: (!prevState.isUpdating),
        });
        console.log('Updated!');
        console.log('Is loading:' + prevState.isLoading)
    }

    render() {

        if (this.state.isLoading) return <Spinner/>;

        return (
            <Grid
                store={this.store}
                plugins={['pagingtoolbar', 'listpaging']}
            >
                The Grid
            </Grid>
        )
    }
    }



    export default withRouter(Subscriptions);

Any idea of what I'm doing wrong?

EDIT: Well, I first thought that the store load wasn't going to trigger the componentDidUpdate method, that's why I wrote the isUploading state separately. I'm removing it but I still didn't solved my problem.

How can I do to prevent the virtualDOM to re-render after the setState call in componentDidUpdate?

I'm looking for an elegant way to break this loop.


Solution

  • Page changes using ExtReact Paginator strangely aren't triggering the ComponentDidUpdate method. Then, all this doesn't look to be the proper way to change the component behavior. ExtReact documentation looks a bit confusing about this point, I can't see how to override the pagingtoolbar component easily.

    Thanks for your answers!