배움 정리

그날그날 배운것들을 기록하자.

git flow, react spring, useState에 함수호출, DOM 언마운트시 애니메이션, css 이미지 크기, props전달 중 비구조할당, css 중간위치잡기, 타 url로 보내기, react-device-detect, 일정 박스안에 텍스트가 넘칠 때 처리, toLocaleString

하루하루 많은 문제들과 부딪히는데 어찌저찌 해결할때도 있고, 해결하지 못할때도 있다 앞으로도 많은 문제를 만날뿐 아니라 같은 문제들도 만날텐데 같은문제가 생길때 다시 또 헤메지 않기위해 배운것들을 기록하려고 한다.

git flow

깃플로우는 한번 정리를 했었는데 내용들은 어느정도 알았지만 어찌 사용해야할지 몰랐다. 직접 사용하게 되면서 사용법을 정리해보자.

설치

일단 git-flow 명령어를 사용하기 위해 homebrew를 사용하여 git-flow를 설치한다.

brew install git-flow

초기설정

flow init -d 명령어는 로컬 저장소에 develop 브랜치를 생성한 뒤 해당 브랜치로 이동한다.

git flow init -d

명령어

git flow <feature | release | hotfix> <start | finish> <branch_name>

피쳐 릴리즈 핫픽스는 저번에 정리한 그 내용이다.

사용 예

start: 새로운 브랜치 생성

기능 개발 시작
git flow feature start <branch_name>
배포 시작
git flow release start <branch_name>
수정 배포 시작
git flow hotfix start <branch_name>

finish: 브랜치 병합 후 해당 브랜치 삭제

git flow feature finish <branch_name>
...

프로젝트 적용

최초 적용 개발자

git clone <remote_url>
git flow init -d
git pusj origin develop
git branch --set-upstream-to=origin/develop develop //타 방법

클론하는 개발자

git clone <remote_url>
git checkout -b develop origin/develop
git flow init -d

플로우 사용

특정기능 개발시

git flow feature start <branch_name>
개발 완료 후
git flow feature finish <branch_name>
원격 저장소 반영
git push origin master develop

배포시기

git flow release start <version_name>
git flow release finish <version_name>
git push origin master
git push --tags

react spring

데이터를 받아서 숫자가 다이나믹하게 또로로로롱 올라가는 기능을 구현하려고 라이브러리를 찾아보다가 react spring이라는 라이브러리를 접하게 되었다. 숫자 카운팅 뿐 아니라 이것저것 동적인 웹을 만들기에 유용한 기능들이 많은 라이브러리였다. 일단 숫자카운팅 기능을 위해 공식문서를 보면서 읽고 적용을 시도해보았다.

import { useSpring, animated } from 'react-spring'
...
const props = useSpring({ number: 1 , from: { number:0 }) // 0에서 1까지 점차 올라감
return <animated.span>{props.number}</animated.span> // 에니메이티드로 감싼다

0에서 1까지 순차적으로 올라가는 기능인데 소수점까지 카운팅이 되서 원치 않는 기능이 생겼다.

<animated.span>{props.number.interpolate(x => x.toFixed(0))}</animated.span>

공식문서를 다시 찾아보다가 .interpolate를 써서 자바스크립트의 toFixed를 사용해서 리턴을 해주니 소수점이 해결이 되었다 그러나 카운팅 수가 10만이면 100,000이 아니라 10000 나와서 예쁘지 않았다 그래서 고민을 해보다가 interpolate의 함수안에서 잘 가공하여 리턴해주면 될 것 같아서 시도를 해보았다.

<animated.span>
  {props.number.interpolate(x => {
    const a = x.toFixed(0)
    a.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  })}
</animated.span>

소수점을 짤라서 반올림하고 그 반환값을 스트링화하고 정규식을 활용하여 replace를 해주었더니 원하던 형태로 나왔다.

타입스크립트에서 css파일 모듈 import 에러

타입스크립트로 프로젝트를 진행하면서 난감한 문제들을 매일마다 만나고있다. 나를 크게 당황시켰던 에러중 하나가 css파일을 임포트해서 적용을 시켜야하는데 임포트를 하면 에러가 났다. 그래서 처음에 해결방안을 찾아보다가 적용했던 방법은

const styles = require('../assets/css.css')

이렇게 변수에 담아서 사용을 했다.
하지만 그래도 부족했고 import를 하는 방법을 찾아보다가 declaration파일을 작성하는 방법을 찾았다 일단 src디렉토리에 declaration.d.ts 파일을 생성한다

//declaration.d.ts
declare module '*.scss'

이러면 스타일파일을 임포트 했을때 에러가 잡힌다.

useState에서 함수호출 넣기 함수넣기

const [state, setState] = useState(fucn)

아직 직접 사용은 안했지만 이것저것 자료를 찾아보다 확인한 내용인데 useState로 상태의 초깃값을 설정할때 함수와 함수호출을 넣어주게되었을때는 함수를 넣어주면 처음 렌더링될때만 함수가 실행되는데 함수호출을 하게되면 리렌더링할때마다 함수가 호출된다고한다. 이건 다음에 한번 실험을 해봐야겠다.

const [state, setState] = useState(fucn())

useEffect() 뒷정리 해주고 스크롤 이벤트 감지

스크롤 위치 감지 이벤트발생 기능을 구현하면서도 꽤 내용들이 많이나왔다. 처음에 적용했던 방법은 useEffect에서 윈도우에 스크롤 이벤트를 걸어주고 그스크롤이벤트는 스크롤이 어느정도 내려가면 상태를 바꿔주는 이벤트였다.

useEffect(() => {
  window.addEventListener('scroll', listenToScroll)
}, [])

const listenToScroll = () => {
  const winScroll =
    document.body.scrollTop || document.documentElement.scrollTop
  const height =
    document.documentElement.scrollHeight -
    document.documentElement.clientHeight

  const scrolled = winScroll / height

  if (isTop && scrolled < 0.2) {
    setIsTop(false)
  }
  if (!isTop && scrolled > 0.2) {
    setIsTop(true)
  }
}

자꾸 근데 상태값을 올바르게 체크못하고 상태값을 계속 바꾸는 상황이 생겨서 고민을 해보다가 처음 window에 이벤트가 걸릴때 그떄의 상태값만 기억하는것처럼 결과가 나와서 여러 방법들을 시도해보았다. 그러다가 찾은 방법

useEffect(() => {
  window.addEventListener('scroll', listenToScroll)

  return () => {
    window.removeEventListener('scroll', listenToScroll)
  }
}, [isTop])

상태값이 바뀔때 이벤트를 다시 거는데 뒷정리함수로 리무브이벤트리스너를 해준다. 조금 더 공부하고 이해를 해야할것같은 부분이었다. 뒷정리 함수 내용도 다시 정리해야겠다.

DOM언마운트 시 애니메이션

상태값에 따라 DOM이 마운트되고 언마운트되는 컴포넌트가 있었는데 애니메이션을 주려고 css animation을 적용시켜서 만들었다. 그런데 마운트시에는 애니메이션이 잘 적용이 되었지만 언마운트때는 DOM자체가 없어지므로 애니메이션이 적용이 안되었다. 그래서 fadeIn과 fadeOut 두 가지의 애니메이션을 만들고 상태값에 따라 각각 다른 애니메이션을 적용해주었으며 부모에서 받은 값으로 그 해당 컴포넌트의 상태값을 컨트롤해주는 방법을 적용시키고 찾아보니 onAnimationEnd라는 속성이 있어서 적용해주었다.

//부모의 상태 내려주기
<ScrollTopBtn show={show} />,

//애니메이션 적용 컴포넌트
const ScrollTopBtn = ({ show }: Props) => {
  const [shouldRender, setRender] = useState(show);

  useEffect(() => {
    if (show) setRender(true);
  }, [show]);

  const onAnimationEnd = () => {
    if (!show) setRender(false);
  };

  return (
    shouldRender && (
      <button
        onAnimationEnd={onAnimationEnd}
        style={{
          animation: `${show ? 'fadeIn' : 'fadeOut'} 1s`,
        }}
      >
      </button>
    )
  );
};

이제 DOM이 사라질때도 애니메이션이 잘 적용이 되었다.

css 이미지 크기

프로젝트 진행중 라이브러리 내에서 flexbox로 레이아웃을 잡고 그 내용들을 image들로 채우는데 자꾸 이미지들이 width값을 아무리 설정해줘도 일정 넓이에서 늘어나지 않았다. 이유는 정확히 모르겠다 flex를 없애면 잘 적용이되나 flex만 있다면 width값이 늘어나지 않았다. 그래서 사용한 방법이 한번 min-width값을 주니까 일정 넓이값보다 커지고 그값이 적용이 되었다.

props전달 중 비구조할당에서

대게 부모에서 자식으로 props를 전달할 때 자식에서 비구조할당을 통해 props를 편하게 받는다. 리액트에서 사용자 지정컴포넌트에 속성을 전달할 경우 자식에서는 한 객체안에 그 속성들을 내려받는데 그 객체를 props라고 하는데

// 부모
<Child props="프랍스" />
// 자식
const child = (props) => {
...
props.props // 프랍스
}

const child = ({props}) => {
...
props // 프랍스
}

이렇게 아래처럼 비구조할당을하여 간편하게 접근을 하는데 전개 연산자로 내려줄 시

// 부모
<Child one="하나" two="" three="" />
// 자식
const child = ({one, ...rest}) => {
...
one // 하나
rest // {two: '둘', three: '셋'}
}

이렇게 일부만 명시해주고 전개연산자를 사용하게되면 명시하지않은 프랍스들은 rest에 객체로 담기게 된다. 몰랐던 부분인데 이번에 학습하면서 알게되었다.

css에서 중간위치 잡기

보통 부모의 기준에서 위아래 중간에 위치시키려면 relative속성을 부모에게 주고 자식도 포지션 속성을 준 후 top:50% left:50% 이런식으로 준다 하지만 자식의 크기만큼의 공간이 있기에 정확히 중앙으로 가지 않는다. 그때 추가해야할 속성이

.center {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

트랜스폼 트랜스레이트를 추가해줘서 크기를 고려한 중앙으로 정렬시킨다. 몇번 사용하였지만 필요할때 깜빡하여서 다시 정리를 해본다.

타 url로 보내기

만약 모바일 기기로 해당 페이지를 접속했을시 타 페이지로 redirection 시키는 기능이 있어서 알아보았다. 일단 모바일 기기로 접속했는지를 확인해야했고, 타 페이지로 redirection시키는 방법을 알아야 했다.

react-device-detect

찾아보니 디바이스 디택트라는 라이브러리를 알게되었는데 모바일로 접속했는지, 데스크탑으로 접속했는지를 boolean으로 반환해서 확인해주고 뿐만아니라 어떤기기로 접속했는지 어떤 브라우저를 사용했는지 확인해주는 기능들이 많았다. 매우 유용하게 쓸 수 있는 라이브러리 였다.

import { isMobile } from 'react-device-detect'

if (isMobile) {
  //모바일로 접속했으면 실행
  //데스크탑이면 false므로 비 실행
}

window.location.href

리다이렉션 시킬 때 window.location.href = ‘url’ 을 해주면 해당 url로 리다이렉션을 시켜준다.

```jsx
import {isMobile} from 'react-device-detect'

if (isMobile) {
window.location.href= "해당url"
}

이렇게 하면 모바일로 접속하면 해당 url로 리다이렉션 시키는 기능을 구현할 수 있다.

일정 박스안에 텍스트가 넘칠 때 처리하는 방법

글자들을 보면 긴 글자들이 어느정도 채워줬으면 …으로 잘리거나 그냥 잘리거나 하는 경우가 있다. 처음에는 그 기능은 자바스크립트로 계산해서 하는줄 알았는데 그럴 수 있겠지만 css로도 처리하는 방법이 있었다.

.classname {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

overflow,white-space, ellipsis 속성을 추가하면 그 공간이 넘칠 시 나머지 글자들은 … 처리가 된다 단 오버플로우 히든 속성과 함꼐 사용해야한다.

여러줄 지정할 때

위와같이 적용하면 한줄이 넘칠 때 나머지 글자들이 … 처리되는데 두 줄이나 세 줄을 지정하고 싶을 수도 있다 그 때 사용하는 방법

.classname {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2; /* 줄 수 */
  -webkit-box-orient: vertical;
  word-wrap: break-word;
}

이렇게 하면 두 줄을 넘길 떄 글자 처리가 가능하다 단 브라우저 호환성은 고려해야한다. 더 세부적인 처리 같은건 js를 동반해야 가능할것 같다.

가격 나타낼떄 콤마붙히고 원 단위로 자르기

보통 가격에 대한 데이터를 받을떄 number 타입으로 받게된다. 만원이라면 10000 오천원이라면 5000 이런식으로 받는데 보여주는건 10,000 이나 5,000 로 콤마를 천단위로 끊어서 붙여주고 싶을떄도 있고 끝마다 5,000원이나 5,000₩ 이렇게 붙이고 싶을떄가 있을것이다. 그래서 자바스크립트에 분명 활용할 메소드가 있다고 생각해서 찾아봤다.

toLocaleString

toLocaleString 메소드는 어떠한 숫자의 타입에 형식을 넣어주고 형태를 변환해주는 함수이다.

const number = 5000
const change = number.toLocaleString()

console.log(change) // 5,000
typeof change // string

특정 조건을 넣어주지 않았을떄 천단위로 콤마를 찍어주고 타입은 스트링으로 변하게 된다. 그 후 ₩를 붙이고싶다면 다음과같이 활용할 수 있다.

<p>{`${price.toLocaleStribg()}`}</p>

숫자형태의 데이터가 원하는 형태로 바뀌는것을 확인할 수 있다.

사용자가 스크롤 내리는지 올리는지 감지

어떤 웹사이트들에서는 스크롤을 내리거나 올릴떄 사용자의 스크롤액션에 따라 네비게이션바가 나타나고 사라진다거나 다른 UI를 적용하는 웹들이 있다. 그 기능을 구현해보려고 이것저것 시도해보았다. 그러다가 찾은 방법

const nav = () => {
  const [checkScroll, setCheckScroll] = useState(false)
  // 스크롤액션을 체크할 상태를 하나 관리

  useEffect(() => {
    let prevScrollpos = window.pageYOffset

    const onscroll = function() {
      const currentScrollPos = window.pageYOffset
      if (prevScrollpos > currentScrollPos) {
        setIsDown(false)
      } else {
        setIsDown(true)
      }
      prevSCrollpos = currentScrollPos
    }

    window.addEventListener('scroll', onscroll)
  }, [])
}

일단 스크롤액션에 따른 변경사항을 감지하기 위해 상태관리를 한다.
그리고 스크롤을 내리는지 올리는지 조건을 비교하기위한 함수를 하나 만들어아하는데, 일단 변수 prevScrollpos에 현재 스크롤위치를 담는다, 그리고 onscroll이라는 함수에서 currentScrollPos에 또 현재 스크롤의 위치를 담는다. 그 후 prevScrollpos 와 currentScrollPos를 비교하여 스크롤의 값에따라 내리는지, 올리는지 비교가 가능하다. 그에따른 실행내용을 넣어주고 상태를 바꿔준다. 그리고 useEffect안에서 스크롤 이벤트를 넣어준다.


Written by@jaeyoung-son
배운것을 기록하는 공간입니다.

GitHub