Archive

React.js CSS Animation

|

React.js CSS Animation


  1. Animations in React App

    • 리액트에서 애니메이션을 적용하는 법은 무수히 많다.
    • 그냥 일반적인 방식으로 css에 때려넣어도 적용은 된다.
    Modal {
        transition: all 0.3s ease-out;
    }
    open {
        opacity: 1;
        transform: translateY(0);
    }
    close {
    	opacity: 0;
        transform: translateY(-100%);
    }
    
    • 혹은 keyframes를 이용해도 된다.
    @keyframes ani {
        0% {
            opacity: 0;
            transform: translateY(-100%);
        }
        50% {
            opacity: 1;
            transform: translateY(20%);
        }
        100% {
            opacity: 1;
            transform: translateY(0);
        }
    }
    open {
        animation: ani 0.3s ease-out forwards;
    }
    
    • 하지만 state가 변함에 따라 수정, 삭제 등의 이벤트가 발생하면 문제가 발생한다. 예를 들어 마우스를 클릭하면 모달창이 없어진다고 치자. 위와 같은 방식으로 애니메이션을 걸어도 없어지는 과정에서 re-render가 일어나며 transition이 더 이상 작동하지 않는 것을 볼 수 있다.
    • 이를 극복하기 위한 개발자들의 노력으로 무수히 많은 transition 패키지가 세상에 나오게 되었다. 이는 react팀에서 만든 정식 패키지는 아니지만 많은 사용자들이 animation 효과를 위해 사용하고 있다.
    • 대표적으로 react-transition-group, react-motion, react-move, react-router-transition 등등이 있다.
    • React The Complete Guide에서는 이들 중 react-transition-group의 사용법을 소개하고 있다.
  2. react-transition-group

    • npm install –save react-transition-group
    • import Transition from ‘react-transition-group/transition’
    • 이 패키지에서 제공하는 Transition 태그를 이용한다.
    • 이 태그의 속성으로는 in, timeout, mountOnEnter, mountOnExit, 기타 생명주기 관련 속성들이 있다.
    • in은 show/hide 등 해당 컴포넌트의 진입과 종료의 트리거 역할을 한다. (boolean 형으로 default는 false이다)
    • timeout은 애니메이션 시간으로 거의 필수 속성으로 들어간다. (밀리 세컨드를 그냥 적어도 되고 객체로 appear, enter, exit을 나눠서 각각 시간을 적어줘도 된다. enter와 exit의 default는 0이고 appear는 default로 enter의 값을 따른다)
    • 보통 애니메이션은 화면 밖에 사용자가 볼 수 없는 공간에 ‘존재’하다가 애니메이션이 발동하면 사용자에게 보여주는 방식을 채택한다. 다른 말로 이미 해당 컴포넌트는 마운트가 되어있다는 뜻이다.
    • mountOnEnter 속성을 사용하면 해당 애니메이션 컴포넌트가 실행될 때 브라우저에 마운트되도록 설정할 수 있다.(boolean형으로 default는 false이다)
    • 마찬가지로 unmountOnExit 속성은 애니메이션이 끝나면 브라우저에서 사라지도록 설정할 수 있다. (boolean형으로 default는 false이다)
    • 기타 생명주기 속성으로 onEnter, onEntering, onEntered, onExit, onExiting, onExited가 있으며 주로 익명 함수로 onEnter={() => 동작}와 같이 작성하며 뜻은 이름 그대로이다.
    • 이 외에도 속성이 많은데 공식문서를 참고하자.
    • Transition 태그 안에 state를 매개변수로 익명 함수가 실행되며 함수의 실행문에 css 코드를 적는다. state는 entering, entered, exiting, exited 4단계의 변화를 겪는다. 이를 활용해 css에 적용할 수 있다.
    import Transition from 'react-transition-group/transition';
       
    <Transition in={this.state.show} timeout={1000}>
        {state => (
        	<div
                style= />
        )};
    </Transition>
    


  3. CSSTransition

    • react-transition-group 패키지를 활용한 스타일링의 또 다른 방식으로 CSSTransition을 이용할 수 있다.
    • import CSSTransition from ‘react-transition-group/CSSTransition’;
    • Transition 태그 대신 CSSTransition 태그를 사용한다.
    • state 익명 함수는 더 이상 사용할 수 없으며 그 대신 속성에 classNames={이름}을 주게 되면 이름-enter, 이름-enter-active, 이름-exit, 이름-exit-active 순서로 생명주기를 갖게 된다.
    • 이를 활용해서 css 파일에 애니메이션 효과를 줄 수 있다.
    • enter, exit 는 1 프레임 뒤에 삭제되므로 주로 초기화에 쓰고 보통 active 클래스명을 이용한다.
    import CSSTransition from 'react-transition-group/CSSTransition';
       
    <CSSTransition in={this.state.show} timeout={300} classNames="fade">
    	<div>안녕</div>
    </CSSTransition>
    
    • classNames를 객체로 직접 커스터마이징해서 사용할 수도 있다
    <CSSTransition 
        in={this.state.show} 
        timeout={300} 
        classNames=>
    	<div>안녕</div>
    </CSSTransition>
    


  4. TransitionGroup

    • TransitionGroup는 Transition이나 CSSTransition 리스트를 관리할 수 있다.
    • ul 태그 아래에 많은 li 태그들이 딸려있다고 치자.
    • ul 태그 대신에 TransitionGroup 태그를 사용하고 속성으로 component=”ul” 이라고 명시한다. (default는 div)
    • li 태그들은 각각 CSSTransition이나 Transition 태그로 감싸준다.
    import TransitionGroup from 'react-transition-group/TransitionGroup';
       
    <TransitionGroup component="ul">
    	<CSSTransition timeout={300} classNames="item">
        	<li>안녕</li>
        </CSSTransition>
    </TransitionGroup>
    



참고 자료


reactjs.org - 공식홈페이지

Udemy - React The Complete Guide

React Transition Group

2021-03-03 TIL

|

2021-03-03 TIL


  • 오늘 한 것
    1. 학원 대면수업(15:30~22:00) JSP - 지금까지 배운것들은 MVC1 모델에 적용되는 것이고 이제는 MVC2 패턴을 배우게 되었다. JSP에 스크립트릿을 작성하지 않기때문에 표현식을 바꾸어야했다. JSTL 너무 사용법이 귀찮다.. 아예 JSP 자체가 너무 나랑 맞지 않는다. 자바스크립트랑 리액트가 더욱 좋아진 계기가 되었달까..
    2. 리액트 Animation - 어제 했던 것에 이어서 외부 라이브러리를 이용해서 애니메이션 효과를 주는 방법을 배웠다. 이번 강좌에서 사용한 패키지는 react-transition-group인데 사용법도 그렇게 어렵지 않고 쓸만하다. 기회가 된다면 react-motion이나 react-move와 같은 패키지 사용법도 알아봐야겠다.



  • 내일 할 것
    1. 리액트 공부 Webpack
    2. 학원 대면수업(15:30~22:00) JSP MVC2



  • 끝으로

최근 넥슨, 넷마블 등을 필두로 개발직군쪽에 연봉 대폭인상 운동이 이는듯 하다. 물론 중소기업은 그걸 따라갈 여력은 안되겠지만 그쪽으로 사람이 엄청 몰리면 인력 조달이 시급해져서 일자리가 늘어난다거나?

오늘의 한 줄 총평 : 희망회로 작동


2021-03-02 TIL

|

2021-03-02 TIL


  • 오늘 한 것
    1. 학원 대면수업(15:30~22:00) JSP - 쿠키와 세션 객체를 사용해서 사용자 정보를 저장하고 꺼내서 사용하는 방법과 JAI 라이브러리로 썸네일 이미지를 만드는 방법, JfreeChart로 JSP에서 차트를 그리는 방법, 파입 업로드 방법 등을 배웠다. JfreeChart 같은 경우에는 너무 오래전 기술이기도 하고 그냥 이런 방식이 있구나 정도만 이해하고 넘어갔다. 일단 진도가 너무 빠른지라 따로 차근차근 정리해야겠다.
    2. 리액트 Animation - 리액트에서 애니메이션을 적용하는 방법에 대해 배웠는데 그냥 일반적으로 CSS를 활용해도 되긴하지만 컴포넌트의 생성과 제거 과정에서 transition이 제대로 먹지 않기 때문에 외부 라이브러리를 활용해야한다. 이것을 이용하면 페이지 이동 등 자연스러운 UX를 구현할 수 있다.



  • 내일 할 것
    1. 리액트 공부 Animation 라이브러리
    2. 학원 대면수업(15:30~22:00) JSP



  • 끝으로

요즘 진도가 완전 벼락급으로 빠르다..

오늘의 한 줄 총평 : 순식간


JSP - 페이징 처리

|

JSP - 페이징 처리


게시판의 페이징 처리를 구현해보자.

먼저, DAO의 게시판 글 리스트를 긁어오는 메소드를 작성한다.

이때 매개변수는 시작과 끝을 명시하는 int를 받는다. 한 페이지에 게시글을 5개만 보여주기로 했다면 쿼리문에서는 ref 내림차순, step 오름차순으로 정렬한 데이터에 번호를 매겨 차례로 5개씩 끊어와야한다. 이를 위해서 where 조건에 시작과 끝을 삽입해준다.

// 게시판 글 불러오기(전체)
	public List<BoardVO> getArticles(int start, int end) {
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		List<BoardVO> articleList = null;
		try {
			conn = ConnUtil.getConnection();
			pstm = conn.prepareStatement("select * from (select rownum rnum, 
                num, subject, ref, step, depth, content from 
                (select * from board order by ref desc,step asc)) 
                where rnum>=? and rnum<=?");
			pstm.setInt(1, start);
			pstm.setInt(2, end);
			rs = pstm.executeQuery();
			if(rs.next()) {
				articleList = new ArrayList<BoardVO>(end-start+1);
				do {
					BoardVO article = new BoardVO();
					article.setNum(rs.getInt("num"));
					article.setSubject(rs.getString("subject"));
					article.setRef(rs.getInt("ref"));
					article.setStep(rs.getInt("step"));
					article.setDepth(rs.getInt("depth"));
					article.setContent(rs.getString("content"));
					articleList.add(article);
				} while(rs.next());
			}
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) try {rs.close();} catch(SQLException e) {}
			if(pstm != null) try {pstm.close();} catch(SQLException e) {}
			if(conn != null) try {conn.close();} catch(SQLException e) {}
		}
		return articleList;
	}


게시글을 보여줄 list.jsp 에 한 페이지에 보여줄 게시글의 개수(pageSize)를 선언한다.

현재 페이지를 뜻하는 currentPage는 파라미터로 넘어온 pageNum을 int로 형변환하여 대입한다.

아무것도 넘어온 값이 없으면 pageNum의 초기 설정은 1로 한다.

<% 
	int pageSize = 5;
	String pageNum = request.getParameter("pageNum");
	if(pageNum == null) {
        pageNum = "1";
    }
	int currentPage = Integer.parseInt(pageNum);
%>


만약 한 페이지에 보여줄 글 개수를 5개로 정했다면 1페이지에는 1~5번의 글이 보여지고 2 페이지에서는 6~10번 글이 보여져야한다.

int startRow = (currentPage - 1) * pageSize + 1; // 시작점
int endRow = currentPage * pageSize; // 끝점


전체 총 글 개수(count)를 DAO에서 불러오고 만약 글 개수가 0보다 크면 위의 시작점(startRow)과 끝점(endRow)을 토대로 DAO에서 글 리스트를 긁어오고 제일 첫번째 글의 글번호(number)를 계산한다.

<%
	int count = 0; // 총 글개수
	int number = 0; // 글번호
	List<BoardVO> articleList = null;
	BoardDAO dao = BoardDAO.getInstance();
	count = dao.getArticleCount(); 
	if(count > 0) {
		articleList = dao.getArticles(startRow, endRow);
	}
	number = count - (currentPage - 1) * pageSize; 
%>


전체 총 글개수가 0보다 클 때 페이징 처리를 할 수 있는데, 만약 보여줄 글 개수가 5개고 총 게시글 수가 11개라고 치자. 2페이지까지 1~10번의 글을 보여주고 마지막 11번째 글은 3페이지에 위치하게 된다. 즉, 전체 총 글개수를 보여줄 글 개수로 나누었을 때 나누어 떨어지느냐가 관건이다. 나누어 떨어지지 않는다면 한 페이지를 더 생성해야 할 것이다. 이를 temp라고 하자. 삼항 연산자로 temp는 나누어떨어지면 0, 그렇지 않으면 1로 설정하고 페이지 개수를 계산한다.

전체 총 글개수를 보여줄 글개수로 나누고 temp를 더한다.(pageCount)

<%
	if(count>0) {
		int temp = count % pageSize == 0 ? 0 : 1; 
		int pageCount = count / pageSize + temp; // 페이지 개수
%>


그 다음, 페이지를 몇 개로 나누어 보여줄지(pageBlock)를 정한다.

pageBlock이 3이라면 처음 페이징은 1, 2, 3을 보여주고 next 버튼을 눌렀을때 4, 5, 6이 나오게 된다. 즉, 현재 페이지가 1이건 2건 3이건 페이징은 1, 2, 3이 나와야 한다. 현재 페이지 - 1을 pageBlock으로 나누었을때 현재 페이지가 4는 되어야 계산값이 1을 넘길 것이다. 마찬가지로 7은 되어야 계산값이 2를 넘긴다. 이를 수식으로 풀면 다음과 같다.

<%
	int pageBlock = 3;
	int startPage = (int)((currentPage-1)/pageBlock) * pageBlock + 1;
	int endPage = startPage + pageBlock - 1;
	if(endPage > pageCount) endPage = pageCount;
%>


여기에 반복문으로 페이징 숫자를 출력하고 추가적으로 이전, 다음과 같은 버튼을 넣어준다.

<%
	if(startPage > pageBlock) {
%>
		<a href="list.jsp?pageNum=<%=startPage - pageBlock %>">[이전]</a>
<%
		}
		for(int i=startPage; i<=endPage; i++) {
%>
		<a href="list.jsp?pageNum=<%=i %>">[<%=i %>]</a>
<%
		}
		if(endPage < pageCount) {
%>
		<a href="list.jsp?pageNum=<%=currentPage+1 %>">[다음]</a>
<%
		}
%>



참고 자료


KG 아이티뱅크 강의 자료

처음해보는 JSP&Servlet 웹 프로그래밍

2021-02-26 TIL

|

2021-02-26 TIL


  • 오늘 한 것
    1. 학원 대면수업(15:30~22:00) JSP - 게시판의 페이징 기법에 대해 배웠다. 역시나.. 예상한대로 어려웠다. 로직 자체는 이해해도 이걸 과연 백지상태에서 머리로만 구현을 할 수 있을지가 의문이다. 많은 연습이 필요하겠지.. 이번 주말동안 최대한 안보고 구현할 수 있도록 연습해봐야겠다
    2. 리액트 Next.js - Next를 이용한 에러처리, 스타일링, 생명주기 메소드, 배포 등에 대해서 배웠다 스타일링은 기존의 리액트에서 하던대로 모듈화해서 적용해봤는데? 됐다. 이게 된다면 굳이 styled-jsx를 쓸 필요가 있겠는가..?



  • 내일 할 것
    1. 리액트 공부
    2. JSP 게시판 만들기 연습
    3. SQL 시험



  • 끝으로

아 맞다 시험..

오늘의 한 줄 총평 : 시험..