본문 바로가기

개발/react 생태계

react에서 infinite-scroll

반응형

이번 시간은 infinite-scroll을 구현할까합니다.

infinite-scroll, react-infinite-scroll-component 

들이 있는데 흠 구현이 안되더라고요.....

 

react에서 window, document접근과 scroll eventlistener을 쓰기 어려워 약간 해맸는데요. 방법은 다음과 같습니다.

 

 

//사용하고자 하는 component div 위치에 onScroll 이벤트를 등록시킵니다. row와 count관리를 위해 state도 등록시켜줍니다

class A extends Component {

	
  constructor(props) {
    super(props);
      this.state = { 
        story: {
          count : "",
          data: ""   
        }
      };
  };
  
  	//초기값은 componentDidMount을 이용해 적용시켜줍니다.
	componentDidMount() {
    
      let url_story = "url?count="+0

      let story_response = await axios.get(url_story)
      .catch((err) => {
        console.log(err)
        return
      });

		this.setState({
          count: 3 // 증가 횟수
          data: story_response.data
        })
    }
    
    
//class 안에서 scroll 함수를 작성해줍니다.

  scroll = async (e) => {
    let target = e.target;
    let inner_height = target.clientHeight// target의 높이 
    let scroll_height =target.scrollTop// 스크롤 한 높이 
    let all_height = target.scrollHeight// 마진 제거한 전체 스크롤 높이 
    
    //가장 밑바닥일 경우
    if(inner_height+scroll_height === all_height) {
      
      let count = this.state.story.count, url_story = "url?count="+count
    
      let story_response = await axios.get(url_story)
      .catch((err) => {
        console.log(err)
        return
      });
		
        //스크롤 할 값이 있을때
      if(Object.keys(story_response.data).length !== 0) {
        let ob = this.state.story.data, last_ob = ob.length, response = story_response.data;
		
        //response의 키값을 ob의 마지막 값보다 1 크게 조정해서 response를 ob에 붙이기. (ob.length가 실제 갯수보다 1이 커서 last_ob = ob.length 사용했습니다 )
        for(let i = 0; i< last_ob; i ++ ) {
            if(response[i]) {
            ob[i+last_ob] = response[i]
          }
        }

      
        this.setState({
          story: {
            count : count+3, // 증가 횟수
            data: ob
          }
        })
      }
      

    }

  
  }
      



	render() {
    return (
      <div className={css.maxSize} onScroll = {this.scroll}>
      	... 
      </div>
    
    );
   	}
}

 

 

// 초기 데이터

count = 0으로 componentDidMount()을 이용해 초기 state값을 가져옵니다. 이후에는 this.scroll로 밑바닥일 경우에만 가져옵니다.

 

 

 

// 스크롤 위치 가져오기

document 개념으로 스크롤 위치를 가져오는게 보통 javascript와 달라, react에서는 component 개념으로 접근해야 했습니다.

 

e.target.clientHeight => target의 높이 

e.target.scrollTop=> 스크롤 한 높이 

e.target.scrollHeight=>마진 제거한 전체 스크롤 높이 

 

 

이기에, e.target.clientHeight+ e.target.scrollTop = e.target.scrollHeight으로 스크롤이 가장 밑바닥일 경우의 조건문을 만들수 있었습니다.

 

count는 this.state.story.count+ 3 로 설정해서 3씩 커기게 했습니다.

 

 

 

 

// 쿼리문 작성

쿼리문 작성은 평소와 같게

 

`select * from table_name where ~~ order by ~~ limit ?, 3`

 

여기서 ?는 몇번째 부터 가져올지를 의미 하고, 뒤에 있는 3은 3개씩 가져옴을 의미합니다.

 

`select * from table_name where ~~ order by ~~ limit 10, 3`은 10번째부터 3개씩이 되겠죠??

 

 

 

 

요약:

# state에서 count와 data를 다룬다.

# react에서 컴포넌트 개념으로  target의 높이(e.target.clientHeight),  스크롤 한  높이(e.target.scrollTop),  마진 제거한 전체 스크롤 높이 (e.target.scrollHeight) 으로 밑바닥일 경우 데이터 가져올경우

# 쿼리문 작성시 limit ? , n( ? : 몇번째, n: 몇개씩)

 

 

끝!

 

##보기 어려우시면 이 링크로 봐주세요:

https://medium.com/%EB%8F%84%EA%B9%A8%EB%B9%84-%EC%9D%B4%EC%95%BC%EA%B8%B0/react%EC%97%90%EC%84%9C-infinite-scroll-ecfc63c57de0