TIL 220804

HaByungNo·2022년 8월 4일
0

Today I Learned

목록 보기
7/16
post-thumbnail

Done 😁




Learned 👌

Javascript 형변환(type conversion)

함수와 연산자에 전달되는 값은 대부분 적절한 자료형으로 자동 변환됩니다. 이런 과정을 "형 변환(type conversion)"이라고 합니다.

문자형으로 변환
무언가를 출력할 때 주로 일어납니다. String(value)을 사용하면 문자형으로 명시적 변환이 가능합니다. 원시 자료형을 문자형으로 변환할 땐, 대부분 그 결과를 예상할 수 있을 정도로 명시적인 방식으로 일어납니다.


숫자형으로 변환
수학 관련 연산시 주로 일어납니다. Number(value)로도 형 변환을 할 수 있습니다.

숫자형으로의 변환은 다음 규칙을 따릅니다.

전달받은 값형 변환 후
undefinedNaN
null0
true / false1 / 0
string전달받은 문자열을 “그대로” 읽되, 처음과 끝의 공백을 무시합니다. 문자열이 비어있다면 0이 되고, 오류 발생 시 NaN이 됩니다.

불린형으로 변환
논리 연산 시 발생합니다. Boolean(value)으로도 변환할 수 있습니다.

불린형으로의 형 변환은 다음 규칙을 따릅니다.

전달받은 값형 변환 후
0, null, undefined, NaN, ""false
그 외의 값true

형 변환 시 적용되는 규칙 대부분은 이해하고 기억하기 쉬운 편에 속합니다. 다만 아래는 예외적인 경우이기 때문에 실수를 방지하기 위해 따로 기억해 두도록 하자.

  • 숫자형으로 변환 시 undefined는 0이 아니라 NaN이 됩니다.
  • 문자열 "0"과 " "같은 공백은 불린형으로 변환 시 true가 됩니다.




깊은 복사를 해야하는 이유

Reducer 함수에서 State를 조작할 때는 깊은 복사를 해야한다. 이유는 기존 State 원본과 확실히 달라야 하기 때문이다.

객체는 값이 같아도 비교할땐 False로 나온다

{ a : 1 } === { a : 1 }  // false

값은 같아도 서로 다른 주소값을 참조하기 때문이다.
그렇기 때문에 깊은 복사를 통해 원본 배열과 확실히 달려지게 해야
React가 state가 확실히 바뀌었음을 인식하고 리랜더링을 하기 때문이다.

예시 코드

// Redux 의 리듀서 함수
const todos = (state = initialState, action) => {
  switch (action.type) {
      case INPUT_TODO:
        let copyTodosForInp = state    // state를 깊은 복사
        return {
          ...copyTodosForInp,
          todos: [...copyTodosForInp.todos, action.payload],
        };
      default:
        return state;
    }
}

Ducks 패턴

Ducks 패턴은 구조중심이 아니라 기능중심으로 파일을 나눈다. 그래서 단일기능을 작성할때나 기능을 수정할 때 하나의 파일만 다루면 되므로 직관적인 코드작성이 가능하다.

즉, action type, action생성자 함수, saga, reducer를 하나의 파일에서 관리하는것이다.

Ducks패턴에서 각각의 액션/액션함수/리듀서를 모아둔 것을 module이라고 부른다

지켜야할 점
1. reducer는 export default로 내보낸다.
2. action 함수는 export로 내보낸다.
3. 액션타입을 정의할 때 reducer/ACTION_TYPE형태로 적어준다. 이렇게 접두사를 붙여주는 이유는 서로다른 리듀서에서 액션이름이 중첩되는것을 방지하기위해서이다.

이러한 규칙을 지켜서 아래와 같이 하나의 파일에 한가지 기능에 대한 내용을 작성할수 있다.

// widgets.js

// Actions
const LOAD   = 'widgets/LOAD';
const CREATE = 'widgets/CREATE';
const UPDATE = 'widgets/UPDATE';
const REMOVE = 'widgets/REMOVE';

// Reducer
export default function reducer(state = {}, action = {}) {
  switch (action.type) {
    // do reducer stuff
    default: return state;
  }
}

// Action 생성자
export function loadWidgets() {
  return { type: LOAD };
}

export function createWidget(widget) {
  return { type: CREATE, widget };
}

export function updateWidget(widget) {
  return { type: UPDATE, widget };
}

export function removeWidget(widget) {
  return { type: REMOVE, widget };
}
profile
프라고

0개의 댓글