요 며칠간 리액트와 타입스크립트를 공부하면서 아직 자바스크립트 문법에 대한 기초가 부족하다고 생각하여 빠르게 훑었다. 정리하기에는 애매해서 간단하게 기록용으로만! 오늘부터는 다시 리액트랑 타입스크립트를 공부한다.
useReducer
useReducer
는 state를 다루는 훅스의 문법이다. 초기 상태의 initial state를 할당한 뒤, 이에 대한 이벤트가 발생한다. 이 state를 수정하기 위해서는 action
이 필요한데, 이에 대한 action을 코드 상에서 구현해주는 것이다. Action을 실행하려면 dispatch
를 이용하면 된다.
// 초기화
const initialState = {
winner: '',
turn: 'O',
tableData: [['', '', ''], ['', '', ''], ['', '', '']],
}
//action.type(action의 이름)은 상수로 따로 빼주는 것이 좋다.
const SET_WINNER = 'SET_WINNER';
const reducer = (state, action) => {
// 수행할 action
switch (action.type) {
case SET_WINNER:
return {
...state,
winner: action.winner,
};
}
};
const TicTacToe = () => {
const [state, dispatch] = useReducer(reducer, initialState); // 초기화
const onClickTable = useCallback(() => {
dispatch({ type: SET_WINNER, winner:'O' }) // action 수행
}, []);
…
};
자식 컴포넌트가 여러 개가 되니까 비동기인 경우에 생각해야하는 부분이 많아져서 까다롭다.
useRef
와 useEffect
를 이용한 성능 최적화 방법불필요한 컴포넌트가 렌더링될 때 어디서 렌더링이 되는지 알 수 없는 경우, useRef
와 useEffect
를 이용해 찾아볼 수 있다. useRef
에 변할 수 있는 값을 모두 넣어준 뒤, useEffect
를 이용해 탐지한다.
const ref = useRef([]); // 초기화
useEffect(() => {
console.log(rowIndex === ref.current[0], cellIndex === ref.current[1], dispatch === ref.current[2], cellData === ref.current[3]);
ref.current = [rowIndex, cellIndex, dispatch, cellData];
}, [rowIndex, cellIndex, dispatch, cellData]);
변하는 값은 false
로 출력될 것이기 때문에 어느 곳에서 컴포넌트가 리렌더링되는지 알 수 있다.
제네릭은 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 문법이다.
function getText<T>(text: T):T {
return text;
}
getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
제네릭으로 함수를 선언하면 타입마다 함수를 정의해주지 않아도 함수를 사용할 때 타입별로 구분이 가능하다.
제네릭 함수에 타입 힌트를 줄 수 있는 몇가지 방법이 존재한다.
// 1. 인자에 []를 추가해 배열 힌트 주기
function logText<T>(text: T[]): T[] {
console.log(text.length);
text.forEach(function (text) {
console.log(text);
});
return text;
}
// 2. 정의된 타입 이용하기
interface LengthWise {
length: number;
}
function logText<T extends LengthWise>(text: T): T {
console.log(text.length);
return text;
}
// 3. keyof로 객체의 속성을 제약하기
function getProperty<T, O extends keyof T>(obj: T, key: O) {
return obj[key];
}
let obj = { a: 1, b: 2, c: 3 };
getProperty(obj, "a"); // 가능
getProperty(obj, "z"); // 에러. "z"는 "a", "b", "c" 속성에 해당하지 않는다.