안녕 하세요  해회 직구를 시작 하기 전에 꼭 있어야되는 준비물이 중에 중요한 개인통관고유 개인통관고유부호 필요 합니다.

 

발급 하는 방법과 실제 직구 시 이용하는 방법에 대해서 간략하게 알아 보도록 할께요~

 

 

 

개인통관고유부호

 

 

개인통관고유부호라는 것은 해외직구할 때 개인 식별번호로 사용되는 것입니다. 관세청에서 2014년에 개인정보보호법을 개정했습니다. 그래서 주민등록번호 대신에 개인통관고유부호라는 것을 사용하여 개인정보 유출을 방지하고자 것이죠

 

이 부호가 생겨난 지 벌써 5년이 되었음에도 불구하고 해외 직구를 해보지 않는 분들은 이 부호가 뭐지? 하는 경우가 많으실꺼에요. 저도 처음엔 이게 모니 했으니까요. 

하지만 발급 하는 법은 매우 쉽고 소요 시간도 3분정도면 가능 합니다.

 

이제 발급 방법에 대해서 알아 볼까요.

 

먼저 포탈 서비스 페이지 검색어 개인통관고유부호라고 검색 해주세요.

첫번째 나오는 발급전용 사이트에 접속 해주세요. 접속하시면 아래와 같은 화면이 뜰꺼에요.

 

여기서 하단 신청 조회란에서 휴대폰 및 공인인증서 중 원하는 방버을 선택 하시고 이름 , 주민번호를 각각 입력 후 확인 버튼을 누릅니다.

 

 

개인 부호가 없는 분들은 신규 발급 버튼을 클릭 해주세요.

 

 

통신사  선택 및 문자 또는 어플을 통해서 본인 인증 해주세요.

 

여기서 발급 된 내역이 없다면 ?

발급 신청 화면이 뜨고 이름,주민번호,주소,전화번호를 입력 후 등록 버튼을 누르면 발급 됩니다. 

 

이전 개인통관 고유 번호를 발급 된 이력이 있다면 ?

아래 화면 처럼 개인 통관 번호랑 이름 주소 개인정보가 나오게 됩니다.

 

발급이 끝나면 이렇게 P 로 시작 하는 개인통관고유부호를 생성 됩니다. 

 

해외 구매 하실때 통관 부호란에 P로 시작 하는 통관 부호를 넣고 결제 하면 끝!!! 쉽죠? 

 

 

블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

/** 한글을 2byte로 인식하여 length 체크 */
function getByteLength( data ) {
var len = 0;
var str = data.substring(0);

if ( str == null ) return 0;

for(var i=0; i < str.length; i++) {
var ch = escape(str.charAt(i));

if( ch.length == 1 ) len++;
else if( ch.indexOf("%u") != -1 ) len += 2; //Db가 한글을 3byte로 인식하여 2->3
else if( ch.indexOf("%") != -1 ) len += ch.length/3;
}

return len;
}

블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

8. React Hooks 란?

react 2020. 2. 3. 11:58

Hooks 란 ?

 

리액트 V16.8에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태관리를 할수 있는 useState 렌더링 직후 작업을 설정하는 useEffect 등의 기능을 제공 하여 기존의 함수형 컴포넌트에서 할수 없었던 다양한 작업을 할수 있게 해준다.

즉 클래스 형태에서 리액트를 구현 한던걸 함수 방식으로도 구현이 가능 하도록 해준게 hooks 라는 말 같다.

 

이제 부터 hooks 기능을 설명 하나씩 살펴 보겠습니다.

 

  • useState : 가장 기존적인 hook 이며 컴포넌에서 상태 관리를 해야 한다면 이 hook를 사용 하면 됨.
import React from "react";

const Counter = () => {
  const [value, setValue] = useState(0); // 0으로 초기화

  return (
    <div>
      <p>
        현재 카운터 값은 <b>{value}</b> 입니다.
      </p>
      <button onClick={() => setValue(value + 1)}>+1</button>
      <button onClick={() => setValue(value - 1)}>-1</button>
    </div>
  );
};

value : 상태값
setValue : 상태를 설정하는 함수
useState 첫번째 값은 상태값 두번째 원소는 상태를 설정 하는 함수를 뜻한다.

  •  useEffect : 컴포넌트 렌더링이 될떄 마다 특정 작업을 수행 할수 있도록 설정 하는 hook 클래스형에서는 componentDidMount,componentDidupdate를 합친 형태랑 비슷 하다.
import React, { useState, useEffect } from "react";

const Info = () => {
  const [name, setName] = useState("");
  const [nickname, setNickname] = useState("");

  useEffect(() => {
    console.log("렌더링 완료");
    console.log({
      console.log(nickname);
      console.log(name);
    });
     return () => { //리턴을 사용 하게 되면 해당 렌더링 숨김 할때 실행 된다.
      console.log("cleaup");
      console.log(name);
    };
  },[]); // []를 사용 하게 되면 인풋창이 업데이트시 매번 실행 됐던게 처음 렌더링 시점에 실행된다.
  //그리고 처음 렌더링 시점이 아니고 name 값이 변경될떄 실행 하고 싶다면  [name] 넣으면됨

  const onChangeName = e => {
    setName(e.target.value);
  };

  const onChangeNickname = e => {
    setNickname(e.target.value);
  };

  return (
    <div>
      <div>
        <input value={name} onChange={onChangeName} />
        <input value={nickname} onChange={onChangeNickname} />
      </div>
      <div>
        <div>
          <b>이름 :</b>
          {name}
        </div>
        <div>
          <b>닉네임 :</b>
          {nickname}
        </div>
      </div>
    </div>
  );
};

값이 다 변경 되고 페이지 변경이 완료되는 시점에 useEffect 함수가 실행 된다.
  • useReducer : useSate 보다 다양한 컴포넌트 상황에 따라 값을 업데이트 해주고 싶을떄 사용 하는 hook useState 는 값이 변경 될떄만 사용 하지만 useReducer 파라미터 값을 넘겨줘서 조건문을 넣어서 사용 할수 있다. 예시를 보면 알수 있을것이다.
import React, { useReducer } from "react";

function reducer(state, action) {
  console.log(state);
  switch (action.type) { //type 를 받아서 조건을 나눠서 처리가 가능 하다.
    case "INCREMENT":
      return { value: state.value + 1 };
    case "DECREMENT":
      return { value: state.value - 1 };
    default:
      return false;
  }
}

const Counter = () => {
  const [state, setValue] = useReducer(reducer, { value: 0 }); 
  // useReducer 함수 첫번째 소요에 실행된 함수를 넣어 준다.

  return (
    <div>
      <p>
        현재 카운터 값은 <b>{state.value}</b> 입니다.
      </p>
      <button onClick={() => setValue({ type: "INCREMENT" })}>+1</button>
      //INCREMENT 조건에는 +1을해주고 있다.
      <button onClick={() => setValue({ type: "DECREMENT" })}>-1</button>
      //DECREMENT 조건에는 -1을해주고 있다.
    </div>
  );
};


useReducer을 통해 input 상택 값을 조절 할수도 있다.  input 이 여러개 일때 하나로 사용 가능하다. 

예시를 보는게 이해에 도움이 될듯 하다. 

import React, { useReducer } from "react";

function reducer(state, action) {
  console.log({
    ...state, //name: state.name,nickname: state.nickname 같은 의미
    [action.name]: action.value
  });

  return {
    ...state //name: state.name,nickname: state.nickname 같은 의미
    [action.name]: action.value
  };
}

const Info = () => {
  const [state, dispatch] = useReducer(reducer, {
    name: "",
    nickname: ""
  });
 
  const { name, nickname } = state;// name, nickname 을 state 오르젝트에 담아서 하나로 사용.
  const onChange = e => {
    dispatch(e.target);
    //input을 통으로 넘겨 준다. 이걸로 인해 input 여러가지 일때도 하나로 재활용이 가능.    
  };

  return (
    <div>
      <div>
        <input name="name" value={name} onChange={onChange} />
        <input name="nickname" value={nickname} onChange={onChange} />
      </div>
      <div>
        <div>
          <b>이름 :</b>
          {name}
        </div>
        <div>
          <b>닉네임 :</b>
          {nickname}
        </div>
      </div>
    </div>
  );
};

export default Info;

  • useMemo : 컴포넌트 내부에서 발생 하는 연상을 최적화 할수 있다. 

아래 예시는 useMemo 를 사용 하지 않았을때 이렇게 사용 하면 input 값이 입력 될때마다 getAverage 실행된다.

import React, { useState} from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const onChange = e => {
    setNumber(e.target.value);
  };

  const onInsert = e => {
    const nexList = list.concat(parseInt(number));
    setList(nexList);
    setNumber("");
  };

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {getAverage(list)}
    </div>
  );
};

export default Average;

useMemo 적용 한 예시 적용을 하게 되면 input 에 입력 될시 마다 아니고 값이 새롭게 입력 될떄만 작동하게 됩니다.

이렇게 하게되면 리렌더를 방지 할수있고 효율이 좋아 진다고 생각 하면 될듯 하다.

import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");

  const onChange = useCallback(e => {
    setNumber(e.target.value);
  }, []);

  const onInsert = useCallback(
    e => {
      const nexList = list.concat(parseInt(number));
      setList(nexList);
      setNumber("");
    },
    [number, list] 
  );

  const avg = useMemo(() => getAverage(list), [list]);  //리스트가 변경 될떄만 실행
  
  return (
    <div>
      <input value={number} onChange={onChange}/>
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {avg}
    </div>    
  );
};
  • useRef : 컴포넌트에서 ref를 쉽게 사용 할 수 있도록 해주는 hook
import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const inputEl = useRef(null); //ref 초기값

  const onChange = useCallback(e => {
    setNumber(e.target.value);
  }, []);

  const onInsert = useCallback(
    e => {
      const nexList = list.concat(parseInt(number));
      setList(nexList);
      setNumber("");
      inputEl.current.focus(); //해당 인풋창에 포커싱
    },
    [number, list] 
  );

  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input value={number} onChange={onChange} ref={inputEl} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {avg}
    </div>
  );
};

export default Average;

간략하게 hooks 기능들을 살펴 봤다 더 자세한 자료를 원한다면 참고 자료 링크를 공유 할테니 참고 해주시면 됩니다.

 

참고 링크 :

https://nikgraf.github.io/react-hooks/

https://github.com/rehooks/awesome-react-hooks

https://velog.io/@velopert/react-hooks

https://ssangq.netlify.com/posts/react-memo-useMemo-useCallback

https://ko.reactjs.org/docs/hooks-intro.html

'react' 카테고리의 다른 글

7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
2. JSX 란  (0) 2019.12.03
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

프론트 하다 보면 자주 쓰는 함수가 있는 map 함수 이다.

 

map 함수는 기존에 forEach 함수랑 비슷 하다고 생각 하면 된다.

 

배열.map((요소, 인덱스 , 배열) => { return 요소});

 

const arr = [1,2,3,4,5,6];

let mapArr = arr.map((v) => {return v});

결과값 : [1, 2, 3, 4, 5, 6]

 

 

reduce 함수는 가끔 볼수 잇는 함수 인데 이해를 잘 못하고 사용 하는 경우가 많았던 함수 같다.

 

이번 기회에 알고 넘어가 보자는 생각으로 찾아 보고 이해를 하기 시작 했다.

 

먼저 reduce 줄이다 라는 의미를 가지고 있고 배열을 순회 하면서 인덱스 데이터를 줄여가며 어떤한 기능을 수행 할수 있다 라고 하지만 의미를 봐서 도통 이해가 가질 않는데 직접 코드를 돌리면서 이해가 필요한 부분인것 같아서 예시 코드를 가지고왔다.

ex1)

const numberList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
const initValue = 0;
 
const totalResult = numberList.reduce((initialValue, currentValue, currentIndex, array) => {
    console.log('initialValue',initialValue);
    console.log('currentValue',currentValue);
    return initialValue + currentValue;
}, initValue);

결과값 :

initialValue 0,currentValue 1
initialValue 1,currentValue 2
initialValue 3,currentValue 3
initialValue 6,currentValue 4
initialValue 10,currentValue 5
initialValue 15,currentValue 6
initialValue 21,currentValue 7
initialValue 28,currentValue 8
initialValue 36,currentValue 9
initialValue 45,currentValue 10

 

reduce(initialValue, currentValue, currentIndex, array) 에서 

 

initialValue : initValue => 0 

currentValue : 값은 numberList 배열 값들이 순차적으로 들어간다. 

currentIndex : 배열 인덱스 값 

생각 하면 됩니다. 여기서 덧셈을 해주는 코드 인데 initialValue값은 초기에 0으로 시작 하지면 뎃셈값이 계속 들어가면서 증가 하는걸 알수 있다. 이렇게 누적으로 덧셈값을 더해서 값을 출력 할때 유용하게 쓰이고 있다.

 

ex2)

const fruit = ['apple', 'grape', 'banana', 'apple', 'orange', 'grape', 'apple', 'orange'];
 
const result = fruit.reduce((object, currentValue) => {
    console.log('object',object);
    console.log('object[currentValue]',object[currentValue]);
    if (!object[currentValue]) {
        object[currentValue] = 0;
    console.log('currentValue',currentValue)
    console.log('count',object[currentValue]);
    }
    object[currentValue]++;
 
    return object;
}, {});
 
console.debug(result);

결과 값 
object {}
object[currentValue] undefined
currentValue apple
count 0
object {apple: 1}
object[currentValue] undefined
currentValue grape
count 0
object {apple: 1, grape: 1}
object[currentValue] undefined
currentValue banana
count 0
object {apple: 1, grape: 1, banana: 1}
object[currentValue] 1
object {apple: 2, grape: 1, banana: 1}
object[currentValue] undefined
currentValue orange
count 0
object {apple: 2, grape: 1, banana: 1, orange: 1}
object[currentValue] 1
object {apple: 2, grape: 2, banana: 1, orange: 1}
object[currentValue] 2
object {apple: 3, grape: 2, banana: 1, orange: 1}
object[currentValue] 1

result 값 :
{apple: 3, grape: 2, banana: 1, orange: 2}

 또한 이렇게 사용도 가능 하다. 배열값 중에서  해당 배열 갯수를 알수도 있다. 덧셈,뺄셈,곱하기,나머지 계산 등등 조건을 다르게 해서 사용 할수 있다. 

 

예시를 봐도 이해가 잘 되지 않는다면 예시 코드를 콘솔창에 넣고 값을 바꿔 가면서 확인 하면 좀더 이해가 쉬울것이다 

필자도 이해가 안가서 값을 다 찍고 변경 하면서 이해를 했다.

 

그래도 이햬가 안간다면 

 

참고 자료를 보고 다시 한번 보는걸 추천 한다.

 

참고 자료 

 

https://www.zerocho.com/category/JavaScript/post/5acafb05f24445001b8d796d

https://youngban.tistory.com/47

블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

리액트 라이플사이클은 크게 마운트, 업데이트, 언마운트 카테고리로 나눌수 있다.

 

시작하기 앞서 라이플 사이클 동작 구조를 그림을 보고 넘어 가겠다.

 

라이프 사이클 동작 순서

  • 마운트란 ?
    • DOM이 생성 되고 웹상 나타나는것을 마운트라고 한다. 
      • 메서드 종류
        • constructor : 컴포넌트를 새로 만들떄 마다 호출 되는 클래스 생성자
        • getDerivedStateFromProps : props 에 있는 값을 state 에 넣어서 사용 하는 메서드
        • render : 준비한 UI를 렌더링 하는 메서드
        • componentDidMount : 컴포넌트가 웹상 나타난 후 호출 하는 메서드
          • setTimeout,setInterval , 네트워크 요청 같은 비동기 작업을 이 메서드에서 처리 하면 된다.
  • 업데이트 
    • 컴포넌트가 4가지 경우 업데이트를 한다. 
      1. props 가 바뀔때
      2. state 가 바뀔때
      3.  부모 컴포넌트가 리렌더링될 때
      4. this.forceupdate 로 강제로 렌더링을 트리거 할때
    • 메서드 종류 
      • getDerivedStateFromProps : 마운트 과정과 업데이트과정에 호출 props 의 변화에 따라 state 갑에도 변화를 주고 싶을떄 사용
      • shouldComponentUpdate : 컴포넌트가 리렌더링 진행 여부를 결정한다. 기본은 true 이고 false 값을 주면 작업 중지를 할수 있다. 특정함수에서 this.forceUpdate() 함수를 호출 하면 이 과정을 생략 할수있음
      • render : 컴포넌트 리 렌더링 
      • getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 직전 호출 메서드
        • 업데이트 하기 직전에 참고할 일을 있을떄 활용이 가능(ex: 스크롤바 위치 유지)
      • componentDidUpdate : 컴포넌의 업데이트 작업이 끝난 후 호출 되는 메서드
        • prevProps or prervProps 사용 하여 컴포넌트 이전 값을 접근이 가능 하고 getSnapshotBeforeUpdate 에서 반환값이 있다면 snapshot 값을 전달 받을수 있음
  • 언 마운트 
    • 마운트의 반대 과정 즉 컴포넌트를 DOM에서 제거 하는 것을 언마운트(unmount)라고 한다.
      • 메서드
        • componentWillUnmount : 컴포넌트가 웹상 사라지기 전에 호출 하는 메서드
          • componentDidMount 에서 등록한 이벤트를 여기서 제거 작업을 해야된다.
  •   마지막으로 그림에는 없지만 componentDidCatch 메서드가 v16에서 추가 되었다. 
    • 컴포넌트 렌더링 도중 에러가 발생 했을떄 애플리케이션이 먹통 되지 않고 UI를 보여 줄수 있게 해준다
  • 사용 예시
componentDidCatch(error, info) {
	this.setState({
    	error : ture
    })
    console.log({eror, info});
}

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
2. JSX 란  (0) 2019.12.03
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

2. JSX 란

react 2019. 12. 3. 14:45

1. JSX 란?

JSX는 자바 스크립트 확장 문법이며 XML 비슷 하게 생겼지만 자바스크립트 문법은 아니다.

리액트는 JSX 를 통해 번들링 해서 사용하기 편하게 만들어 졌다고 생각 하면된다.

 

JSX 문법

function App() 
{
	return (
    	<div> 
        	Hellp <b>react</b>
        </div>
    )
}

javascript 문법

function App()
{
	return React.createElement('div',null,'Hello', React.createElement('b',null,'react'));
}

비교 한거와 같이 JSX 문법을 사용 하게 되면 좀더 쉽게 사용 할수 있다. 하지만 JSX를 쓰기 위해서는 몇가지 규칙이 존재한다.

 

1. 컴포넌트에 여러 요소가 있다면 반드시 부로 요소 하나로 감싸야한다. (여러개를 하나의 요소로 감싸서 사용 하는 이유는  Virtual DOM에서 컴포넌트 변화를 감지 해낼떄 효율적으로 사용 하기 위에서 규칙 존재)

function App()
{
	return (
    	1. div 를 사용
        <div> //부모요소로 감싸준다. 
        	<h1>리액트 하이</h1>
            <h2>리액트 하이</h2>
        </div>
        
        2. div 를 생략 하고 사용 한다.
        <> //부모요소로 감싸준다. 
        	<h1>리액트 하이</h1>
            <h2>리액트 하이</h2>
        </>
    )
}

2. JSX 에서 javascript 문법 

improt React from 'react';

function App() 
{
	const name = '리액트';
    return (
    	<>
        	<h1>{name} 하이</h1>
            <h2>잘 작동 하니</h2>
        </>
    )
}

3. if 문 대신 조건부 연산자( {} 안에  () 사용 하는경우는 줄바꿈이 일어나서 코드를 작성 할때 사용) 

improt React from 'react';

function App() 
{
	const name = '리액트';
    return (
    	<>
        1. 
        { name === '리액트' ? (<h1>리액트 입니다.</h1>) : (<h1>리액트 아닙니다.</h1>)};
        2.
        { name === '리액트' ? <h1>리액트 입니다.</h1> : null };
        3. 
        { name === '리액트' && <h1>리액트 입니다.</h1>};
        
        </>
    )
}

4. undefined 를 렌더링 하지 않는다.

improt React from 'react';

function App() 
{
	const name = undefined;
    return (
 		return name;  //오류 발생 
        해결방법
        1. OR 연산자 사용
        return name  || '값이 undefined'입니다.;
        2. JSX 내부에서 undefined 사용 
        return <div>{name}</div>
        3. JSX 내부에 OR 연산자 사용 (name 값이 undefined 일떄 보여줄경우)
        return <div>{name || '리액트'}</div>
    )
}

5. 인라인 스타일은 객체로 반환 (카멜 표기법 사용)

ex ) font-size => fontSize 

 

6. class 대신 className 을 사용

 

7. 꼭닫아야 하는 태그가 존재함 

<input> => <input />

<br> => <br />

<p>  => <p />

 

8. 주석 사용법 

 

평소에 javascript 사용하는 주석 방법

1. // 

2. /* */

 

JSX 주석

1. { /* 주석을 사용한다. */}

 

 

이와 같이 몇가지 규칙이 존재 하지만 규칙 특별하게 어렵지 않고 사용 하다 보면 익숙해 져서 편안하게 사용이 가능 할라꺼라고 생각한다.

 

 

 

 

 

 

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

1. 리액트 시작

react 2019. 12. 3. 13:30

1. 왜 리액트 인가?

 

javascript 로 비동기 처리를 할라면 업데이트 하는 항목에 따라 어떤 부분을 찾아서 변경할지 규칙을 정하는 작업은 간단 하지만 그 규모가 크면 상담히 복잡 해지고 관리가 제대로 되지 않으면 성능 저하가 올수 있다.

그래서 페이스북 개발팀에서 해결할라고 나온데 리액트 이다.

리액트는 변경할때마다 어떤 변화를 줄지 고민 하는것이 아니라 기존 뷰를 날려 버리고 처음부터 렌더링 하는 방식이다.

이렇게 바뀌면서 구조도 심플해지고 작성 해야할 코드양이 많이 줄이 든다. 

 

2. 리액트의 이해 

 

리액트는 자바 스크립트 라이브러로 사용자 인터페이스를 만드는 사용 한다. mvc,mvw 등 프레임워크와 달리 오직 V(View)만 신경 쓰는 라이브러리 입니다. 

특정 부분이 어떻게 생길지 정하는 선언체(컴포넌트)를 통해 초기 렌러링과 리 렌더링을 한다. 

리액트는  Virtual DOM을 사용 해서 기존 DOM 과 새로운 DOM을 비교 해서 변경이 된 DOM 적용 하게 된다.

절차는 아래와 같다.

 

1. 데이터를 업데이트 하면 전체 UI를 Virtual DOM에 리렌더 합니다.

2. 이전 Virtual DOM에 있던 내용과 현재 내용을 비교 합니다.

3. 바뀐 부분만 실제 DOM에 적용 합니다.

 

이렇게 전체 DOM을 바꾸는게 아니고 변경이 필요한 부분만 교체 하기 떄문에 CPU 과부화를 줄일수 있고 전체 를 변경 할떄 끊김현상을 해결할수 있게 됩니다.

 

3. 환경 설정

 

1. node 와  npm 을 설치

node 다운 로드 경로(LTS버전은 설치)  :  https://nodejs.org/ko/download/

설치후 터미널 창에서 npm --version, node --version 실행후 버전이 나오는지 확인 한다.

C:\work\saramin\react>node --version
v10.16.0

C:\work\saramin\react\hello-react>npm --version
6.9.0

 

node 를 설치 후 아래와 같이 npm 을 설치 해준다

npm install -g create-react-app //npm -g 글로벌로 npm 설치 해준다
create-react-app my-app 

cd my-app  
npm start 

또는 npx 를 사용 할수 있다. npx를 사용 하는걸 추천한다. 그 이유는 npx는 최신 버전에 해당하는 패키지를 설치하여 실행하고, 실행된 이후에 해당 패키지를 제거 해주기 떄문이다.

npx create-react-app my-app

cd my-app
npm start

npm start 를 하면 서버가 실행 되고 http://localhost:3000/와 같은 url 생성 될것이다. url 치고 들어가면 아래 같은 React 기본 페이지가 나왔다면 성공!!!

 

 

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
2. JSX 란  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

if kako(2019) 리뷰

세미나 2019. 12. 3. 10:00

오픈소스 데이터베이스, 흐르는 은행 데이터에 빨대를 꽂아보다.

  • 카카오뱅크는?
    • 금융 탈을 소셜 서비스
    • 폭발적으로 늘어나는 데이터

데이터를 분산 재배치를 해보자

  • SQL 데이터 퍼가기
  • CDC 변경분 퍼가기
  • 타이핑 노가다해서 퍼가

SQL 데이터 퍼가기

  • 장점
    • SQL 데이터를 자유롭게 제어
    • 로직에 포함되며, 상대적으로 구조가 간결
  • 단점
    • 소스DB 부하(Select / Index)
    • 지연된 커밋에 따라 데이터 누락 발생 가능

What is Uldra?

  • Source DB -> Target DB 사이에 존재하여 Sharding 지원가능한 소프트웨어
  • JDK 1.8 작성
  • Uldraman 어떻게 구성되어 있을까?
    • BinaryLog Parser 변경분을 파악해서
    • Task Worker 통해 원하는 DB 저장하는 방식
  • Goals
    • 쉽고 정확하고 빨라야 한다.

What is BinaryLog in MySQL?

      • Table Map Event
        • 변경을 가한 테이블 정보
        • 데이터베이스 / 테이블 / 테이블 컬럼 타입
      • Row Event (Write, Delete, Update)
        • Write - 추가 데이터
        • Update - 변경 이전 / 이후 데이터
        • Delete - 삭제 이전 데이터
    • Query Event End

Uldraman 이전 모습은?

  • Kakao ADT 주로 배치 프로세스에 초점
    • 타겟쪽에 구조 변경으로 인해 장애가 발생하더라도
    • 실제로 서비스에는 노출하지 않는다.

하지만 Uldraman?

  • 실제로 서비스하는 온라인 서비스에 포커싱을 맞춘 프로젝트
  • 특급 서비스

Uldraman 사용하기 위해서는?

  • Binary Log format?
    • Row Format으로 기록되는 바이너리 로그여야만 한다.
  • Binary Log Full Image
    • 바이너리 로그에 변경 / 이미지가 모두 포함되어야 한다.

Kakao ADT & Uldraman 공통 목표

  • 복제가 시스템이 이상이 생기는 경우?
    • 실패한 지점부터 다시 시작을 해야하는데..
    • 이를 어떻게 해결할까?
    • Overwrite
      • 덮어쓰다보면 언젠간 맞춰진다.
      • 누락된건 없는지..
      • 성공했던 포지션부터 다시 복사하자!
      • Update Row Event 경우 항상 Delete 발생하는 것은 아니다.
        • 샤드키 혹은 PK 변경 (샤드키는 국적, PK 집주소)
        • YES
          • Delete
        • No
          • Replace
    • Sequential
      • 데이터를 그룹핑하고
      • 동일한 그룹에 있는 데이터는 순차적으로 처리하자.
    • 병렬 처리
      • 연관없는 데이터를 병렬로 처리하면 빠르지 않을까?
      • 1 샤딩
      • 2 샤딩
        • 몇번째 Thread에서 진행할지 결정

Uldraman 가진 Feature

  • Recover Mode
    • 데이터 버젼 체크를 해보자.
    • 언젠가는 데이터가 최신은 되지만.. 정합성을 요구하는 상황이라면?
      • 이를 해결하기 위해 데이터 내용에 버젼을 넣고
      • 데이터 버젼이 낮거나 같으면 Overwrite하는 모습
      • 매번 발생하는 상황은 아님
  • Generate Sharding Key
    • 샤딩키를 만들거나 변형해서, 기준으로 데이터를 분산하자.
  • Performance?
    • 스케일 아웃 경우
      • 1 Node -> Uldraman -> 8 Shard
      • 30,000 rows/sec
    • 스케일인 경우
      • 4 Shard -> Uldraman -> 1 Node
      • 1 Node 내장 DB tokudb 사용하는 상황

2. 초당 옥수수의 취소를 막아라 !

수만건의 주문을 1초내에 처리내에 처리 하는 기술

 

초당 옥수수 ?

처음에 세미나 제목을 듣고 초당 처리 하는 기술이라서 초당 옥수수라는 별칭으로 불리는 구나 생각 했지만 세미나를 듣고 나서 초당 옥수수라는 일반 옥수수의 비해 3배 이상 당도가 높아서 인기가 있는 초당 옥수수라는게 있다는걸 알게되었다. 초당 옥수수는 일반 판매 하는 방식이 아니고 수확 시기가 오면 미리 예약을 받아서 수확하는 동시에 배송 하는 시스템임

하지만 수확을 예측 해서 배송을 하는 시스템상 수확이 어렵거나 날씨에 영향을 받아 배송 지연처리를 하더라도 배치를 돌려서 보내는 방식이었기 때문에 배치 시간이 될 때 까지 기달려야되는 문제가 있었다.

레거쉬 시스템 문제

1.     배송 지연 안내를 위해 배치를 사용 (5분마다 실행)

2.     너무 복잡한 비즈니스 로직

 

레거쉬 시스템의 문제에 대한 개선점

1.     실시간 TMS 발송

A.     단일 머신을 수행 하기에는 한계가 비동기 워커를 구성 메시지 브로커로 BabbitMQ 를 도입

2.     복잡한 비즈니스 코드 리팩토링

A.     기존에 중복된 소스를 하나로 합치고 배송지연처리,주문조회,배송조회,주문 상태 변화 등 모듈화를 통해 리팩토링

3.     처리 속도 개선

A.     반복되는 태스크 수행시 병목이 발생 그래서 비즈니스 처리를 비동기 워커를 구성하여 여러 개의 컨슈머로 처리 해서 대량의 요청을 분산처리를 통해 해결

액터가 된 비동기 워커

-       분석처리

n  쉽게 분산처리를 할수 있도록 개선 스프링 simpllerabbitlitenercontainerfactory 확장 Listener consumer 커스텀 설정

-       자동 재처리 및 실패 감지

n  Consumer 처리시 예외 발생( 1%) 한건에 대해서 Retriable 재처리용 큐를 사용해서 재처리

n  재처리용 큐를 통해서 실패가 된 건들은 큐에 쌓고 관리자에게 카톡으로 알림을 해줘서 직접 처리가 가능 하도록 함

배포 없이 빠르게 롤백 하는 전략 : 전체 구조

이전 배포시에는 배포를 하고 문제가 생기면 롤빽을 하는 방식 이었는데 롤뺵 하는 동안 장애가 발생함 하지만 앞단에 스위치를 둬서 배포 하고 문제가 생기면 스위치 on/off 식으로 사용 하면서 1초만에 이전 버전으로 돌릴 수 있도록 바꾸면서 단점을 해결함

블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,