Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS Loading icon while waiting for data

I'm experimenting with ReactJS, and much of my application relies on loading data from an API, using jQuery to help me with that.

I have loading text/icon setup, but it feels a bit hacky and not very reusable:

ListWrapper = React.createClass({
    getInitialState: function() {
        return {
            loading: true,
            listData: []
        };
    },
    componentDidMount: function() {
        Api.get('/v1/listdata', function (data) {
            react.setState({
                    loading: false,
                    listData: data
            });
        });
    },
    render: function() {
        return (
            <List loading={this.state.loading} data={this.state.listData} />
        );
    }
});

List = React.createClass({
    render: function() {

        var mapData;
        if (this.props.loading)
            mapData = <Loader />; 
        else {
            mapData = this.props.data.map(function(item) {
                return (
                    <ListItem name={item.name} />
                );
            });
        }

        return (
            <div>
                {mapData}
            </div>
        );
    }
});

This works fine, however the whole if/else statement has hints of code smells since I'd have to do that logic all over the place.

Can't really find anything on the web about how to best approach this... Whats a better way?

like image 432
Alias Avatar asked Apr 05 '15 17:04

Alias


People also ask

Why does my React app take so long to load?

The major cause for this issue is adding too many components into a single bundle file, so the loading of that bundle file might take more time. To avoid this kind of issue, we need to structure our components in an optimized way.

How do you show loader while API status is pending in react JS?

showLoader(); ajax(config) . then((response) => { let data; this. props. hideLoader(); data = response.

How do you add a loading animation to React?

import React, { useState, useEffect } from 'react'; const App = () => { const [loading, setLoading] = useState(false); return ( <! -- ... --> ); }; export default App; Note: The state is set to false by default in the code above, and we can change it to true whenever we want the loader-container to appear.


1 Answers

You can simplify your existing code to be less verbose just by removing the else statement:

render: function() {
        if (this.props.loading) {
            return <Loader />;
        }
        var mapData = this.props.data.map(function(item) {
            return (
                <ListItem name={item.name} />
             );
        });
        return (
            <div>
                {mapData}
            </div>
        );
    }

But one solution I can think of is have your component accept a isActive bool and moving the if logic into the loader component instead of the individual components. When isActive = true it shows the spinner/loading icon. Otherwise it just returns a null component or empty .

List = React.createClass({
    render: function() {

        var mapData = this.props.data.map(function(item) {
            return (
                <ListItem name={item.name} />
            );
        });
        return (
            <div>
                <Loader isActive={this.props.isLoading} />
                {mapData}
            </div>
        );
    }
});

This case instead of doing the if logic everywhere, you just do it once in your Loader component, and it just returns null/empty if its inactive.

like image 65
trekforever Avatar answered Sep 24 '22 08:09

trekforever