0

I am trying to get No list items only when there's nothing coming from the backend. Right now, onload, I get the loading spinner and No List items before I fetch the data.

So, I thought I would add a timeout to deal with this so that it will only show up after the fetching is done, and there are no items

 getList() {
        if(this.state.list.length != 0){
            return (this.state.list.map(data => {
              return <div data={data} key={data.id}/>
            }))
        }else{
            return <div>No List items</div>
        }
    }

render() {
        return (
            <div>  
                <Spinner active={this.state.active} />
                <div>{setTimeout(this.getList, 1000)}</div>
            </div>
        );
    }
}

When i use this, I am getting numbers on the browser. The active state of spinner changes on componentDidMount to false

4
  • 2
    setTimeout returns an ID that can be passed to clearTimeout. setTimeout doesn't and cannot return the return value of the callback since setTimeout doesn't actually execute the function at the moment it is called. Using setTimeout in your situation doesn't make sense. Commented Oct 24, 2018 at 20:35
  • @FelixKling so what do you suggest, I should use to delay the "No list items" label before fetching is done. I fi cannot return the value Commented Oct 24, 2018 at 20:39
  • You can have this.state.list be null initially, which would mean that the data has not been fetched from the server yet. Or, assuming that this.state.active is true while the data is fetched and false once it is fetched, you can just do {this.state.active ? null : this.getList()}. Commented Oct 24, 2018 at 20:45
  • See my updated comment. Of course you wouldn't call getList if this.state.list is null. We don't know the rest of your code and what you do with this.state.list so we have to trust that you know how to apply the suggestion to your situation. Commented Oct 24, 2018 at 20:47

3 Answers 3

4

That's what setTimeout returns: an id number, which you can use later if you want to cancel the timeout.

The render method is synchronous. If you want to render nothing for the case where you don't have data, then you can have render return null. Then in componentDidMount, do any async work you need, and when it completes, call this.setState to update the state and rerender (this time without a null)

Sign up to request clarification or add additional context in comments.

3 Comments

I want to render "No items" when i don't get anything
You can do that too. Perhaps start off with state = {list: null}, then fetch the data, then update the state to either have an empty array or a populated array. If list is null, render nothing. If list is empty, render the 'no items' message. If it's neither null nor empty, render the relevant divs.
Great, I will try this. Thanks for you response
1
class Items extends React.Component {
    constructor(props) {
        super();
        this.state = {
            active: true,
            is_loading: false,
        }
    }

    componentDidMount() {
        this.timeout_number = setTimeout(() => {
            this.setState({
                active: false,
                is_loading: true
            });
        }, 1000);
    }

    componentWillUnmount() {
        clearTimeout(this.timeout_number);
    }

    getList() {
        if(this.state.list.length) 
            return this.state.list.map(data => <div data={data} key={data.id}/>)
        else
            return <div>No List items</div>
    }

    render() {
        return (
            <div>  
                <Spinner active={this.state.active} />
                {this.state.is_loading 
                    ? this.getList() 
                    : null}
            </div>
        );
    }
}

export default Items;

Comments

1

Don't use a timeout here. I would just set the initial state of list to null. Then just flip your logic so that it is:

getList() {
        if(this.state.list && this.state.list.length == 0){
            return <div> No List items </div>
        }else{
            return (this.state.list.map(data => {
              return <div data={data} key={data.id}/>
            }))
        }
    }

There are 100 ways to solve this but this is the easiest based on your code. ALso don't forget the difference between != and !==.

1 Comment

Thank you for your response!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.