리액트에서 컴포넌트를 만드는 방법은 크게 두 가지가 있습니다. 클래스 기반 컴포넌트와 함수 기반 컴포넌트 입니다. (React.createClass는 16에서 사라짐). 클래스 기반 컴포넌트(React.Component, React.PureComponent)는 동일하나 차이점이 있다면 shouldComponentUpdate를 포함/미포함 입니다. shouldComponentUpdate는 렌더링 이전 새로운 props와 state를 받았을 경우 실행됩니다.
PureComponent는 shouldComponentUpdate 라이프사이클이 이미 적용된 컴포넌트 입니다. 예를들어, React.Component를 확장해서 컴포넌트를 만들면, shouldComponentUpdate 메소드를 사용하지 않으면, props, state 값이 변경됨에 따라 항상 리렌더링이 됩니다. 반면, PureComponent를 사용하면 내부 shallow level 단계에서 변경된 값이 있을 경우에만 리렌더링 됩니다.
얕은비교(shallow comparison)는 현재 props, state를 nextProps, nextState 객체와 비교하는 것입니다. 반복문을 통해 비교를 진행하며 각각의 객체의 key의 value값이 다르면 true를 반환합니다. 그렇기 때문에, JSON.stringify()와 같은 깊은비교(deep comparison)를 shouldComponentUpdate에서 사용하는 것은 권장하지 않습니다.
깊은비교에 대해 좀 더 자세히 알아보도록 하겠습니다. 자바스크립트에서는 두 객체를 자동으로 비교하는 메소드를 제공하지 않습니다. 변수에 할당된 객체가 같은 객체를 참조하고 있다면 동일하다고 나옵니다. 원시값인 문자열, 숫자는 그 값을 비교하지만, 유사배열, 날짜, 객체는 참조값을 비교하기 때문입니다. 즉, 메모리 상에서 할당된 위치가 같은지 확인합니다.
Reducer
Since one of the core tenets of Redux is to never mutate state, you'll often find yourself using Object.assign() to create copies of objects with new or updated values.
1. Apply없이 배열을 함수의 인수로 사용이 가능
PureComponent는 shouldComponentUpdate 라이프사이클이 이미 적용된 컴포넌트 입니다. 예를들어, React.Component를 확장해서 컴포넌트를 만들면, shouldComponentUpdate 메소드를 사용하지 않으면, props, state 값이 변경됨에 따라 항상 리렌더링이 됩니다. 반면, PureComponent를 사용하면 내부 shallow level 단계에서 변경된 값이 있을 경우에만 리렌더링 됩니다.
얕은비교(shallow comparison)는 현재 props, state를 nextProps, nextState 객체와 비교하는 것입니다. 반복문을 통해 비교를 진행하며 각각의 객체의 key의 value값이 다르면 true를 반환합니다. 그렇기 때문에, JSON.stringify()와 같은 깊은비교(deep comparison)를 shouldComponentUpdate에서 사용하는 것은 권장하지 않습니다.
shouldComponentUpdate(nextProps, nextState) {
return this.state.value != nextState.value;
}
깊은비교에 대해 좀 더 자세히 알아보도록 하겠습니다. 자바스크립트에서는 두 객체를 자동으로 비교하는 메소드를 제공하지 않습니다. 변수에 할당된 객체가 같은 객체를 참조하고 있다면 동일하다고 나옵니다. 원시값인 문자열, 숫자는 그 값을 비교하지만, 유사배열, 날짜, 객체는 참조값을 비교하기 때문입니다. 즉, 메모리 상에서 할당된 위치가 같은지 확인합니다.
const c = {"a":3};
const d = {"a":3};
console.log( c === d ); // false
const x = {"a":3};
const y = x; // x and y holds the same reference
console.log( x === y ); // true
자바스크립트에서 깊은 비교를 하는 가장 간단한 방법은 객체를 JSON 문자열로 바꿔 비교하는 방법입니다. 하지만 순서가 바뀔경우 생기는 문제점이 있습니다.
// comparison by JSON.stringify is not reliable
const x = {"a":1, "b":2};
const y = {"b":2, "a":1}; // reverse order
console.log( JSON.stringify(x) === JSON.stringify(y) ); // false
이에 대한 기본적인 해결방법은 아래와 같습니다. 두 객체를 비교하기 위해서는 반복문을 통해 모든 속성값을 확인해줘야합니다. 하지만, 아래와 같은 비교방법도 모든 예외처리를 다 해줄 수 없기 때문에 잘 만들어진 라이브러리를 사용하는 것이 좋습니다. Underscore와 Lo_Dash에서는 _.isEqual 이라는 객체 비교 메소드를 제공하고 있습니다.
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
// Outputs: true
console.log(isEquivalent(bobaFett, jangoFett));
함수형 컴포넌트는 state, 라이프사이클 메소드, ref 콜백을 사용할 수 없습니다. 많은 기능이 없기 때문에 클래스기반 컴포넌트보다 더 가볍고 뛰어날 수도 있지만 아직 100% 옳지는 않습니다. 우선, 함수형 컴포넌트도 결국 클래스 기반 컴포넌트로 래핑이 되기 때문입니다. 함수형 컴포넌트는 해당 컴포넌트의 자체 기능없이 props를 받으면 뷰의 노출 여부만 제공할 때 사용할 수 있습니다.Reducer
Since one of the core tenets of Redux is to never mutate state, you'll often find yourself using Object.assign() to create copies of objects with new or updated values.
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
Because of its illegible, an alternative approach is to use the object spread syntax proposed for the next versions of JavaScript which lets you use the spread (...) operator to copy enumerable properties from one object to another in a more succinct way.
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return { ...state, visibilityFilter: action.filter }
default:
return state
}
}
Spread Operator1. Apply없이 배열을 함수의 인수로 사용이 가능
function doStuff (x, y, z) { }
var args = [0, 1, 2];
// Call the function, passing args
doStuff.apply(null, args);
//ES6
doStuff(...args);
2. 배열 조합
var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];
// ["one", "two", "three", "four", "five"]
3. 배열 복사
var arr = [1,2,3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4)
Comments
Post a Comment