본문 바로가기
Library | Framework/React

[React] 로딩 중 화면 구현

by 나는김혜린 2022. 1. 18.

서론

이번 글은 저번 글에 이어 페이지가 로딩이 될 때 로딩 중이라는 것을 보여주는 화면을 만들어볼 것이다.

홧팅홧팅

 

지금 로딩 안 느린데요?

그래서 개발자 도구를 켜서 일부러 느린 통신망을 시뮬레이션해보자.

사진대로 느린 3G를 선택하고 새로고침을 하게 되면 엄청 느려지는 걸 확인할 수 있다.

답답ㅎㅎ,,,

 

로딩 중 메세지 표시하기

App.js 코드의 내용을 이렇게 수정하자.

class NowLoading extends Component {
  render() {
    return <div>Now Loading...</div>
  }
}

class App extends Component {
  state = {
    article:{
      item:{title:'Welcome', desc:'Hello, React & Ajax'},
    isLoading:false
  },
    list: {
      items:[],
      isLoading:false
    }
  }

  componentDidMount() {
    var newList = Object.assign({}, this.state.list, {isLoading:true});
    this.setState({list:newList}); 
    fetch('list.json')
    .then(function(result) {
      return result.json();
    })
    .then(function(json) {
      this.setState({list:{
        items:json,
        isLoading:false
      }});
    }.bind(this));
  }

  render() {
    var NavTag = null;
    if(this.state.list.isLoading) {
      NavTag = <NowLoading></NowLoading>
    } else {
      NavTag = <Nav list={this.state.list.items} onClick={function(id) {
        var newArticle = Object.assign({}, this.state.article, {isLoading:true});
        this.setState({article:newArticle});
        fetch(id+'.json')
        .then(function(result) {
          return result.json();
        })
        .then(function(json) {
          this.setState({
            article:{
              item:{
                title:json.title,
                desc:json.desc
              },
              isLoading:false
            }
          })
        }.bind(this))
      }.bind(this)}></Nav>
    }

    var ArticleTag = null;
    if(this.state.article.isLoading) {
      ArticleTag = <NowLoading></NowLoading>
    } else {
      ArticleTag = <Article title={this.state.article.item.title} desc={this.state.article.item.desc}></Article>
    }
    return (
      <div className='App'>
        <h1>WEB</h1>
        {NavTag}
        {ArticleTag}
      </div>
    );
  }
}
state = {
  article:{
    item:{title:'Welcome', desc:'Hello, React & Ajax'},
    isLoading:false
  },
  list: {
    items:[],
    isLoading:false
  }
}

state 구조가 변경되었는데, article과 list에 로딩 중인지 나타내는 isLoading이 추가 됐고 기본값은 false로 설정했다.

기존의 state.article 값은 state.article.item 으로 옮기고, state.list값은 state.list.items로 옮겼다.

그래서 Article의 title, desc props도 변경한다.

fetch('list.json')
    .then(function(result) {
      return result.json();
    })
    .then(function(json) {
      this.setState({list:{
        items:json,
        isLoading:false
      }});
    }.bind(this));

state.list의 구조가 변경됐기 때문에 componentDidMount의 setState도 변경되었다.

-> setState는 로딩이 끝난 다음 호출되기 때문에 로드가 끝나면 isLoading이 false가 되어야 한다.

var newArticle = Object.assign({}, this.state.article, {isLoading:true});
this.setState({article:newArticle});

newArticle이라는 변수에 article 객체를 복사하고, isLoading 값을 true로 할당한다.

state.article을 변경하는 setState는 클릭했을 때 호출되기에 로드가 시작되는 시점이기 때문에

isLoading 값을 true로 정한다.

if(this.state.list.isLoading) {
      NavTag = <NowLoading></NowLoading>
    } else {
    
if(this.state.article.isLoading) {
      ArticleTag = <NowLoading></NowLoading>
    } else {

...

return (
      <div className='App'>
        <h1>WEB</h1>
        {NavTag}
        {ArticleTag}
      </div>
    );

두 개의 if문은 isLoading 값이 true일 때 Nav/ArticleTage를 NowLoading 컴포넌트로 할당한다.

즉, isLoading이 true면 로딩 중 화면을 보여주고 false면 기존 화면을 보여준다는 뜻이다.

 

 

구현 화면

 

담소

오늘은 딩연하지만 많이 생각하지 못 하는 로딩 화면을 만들어 봤는데, 

이해가 잘 안 되는 부분도 쪼매 있었지만 그래도 재밌당 !!

홧팅홧팅

댓글