Web Dev/Log :: 개발일지

개발항해일지 22년/7월/4주 :: 입사 4주차, 리덕스 툴킷, Ant Design, 레거시

HJPlumtree 2022. 7. 24. 21:01

일지 2022년 7월 4주차

 

 

입사한지 4주차

모르는 것도 많고, 혼자 할 수 있는게 많지 않아서 퇴근하면서도 찝찝한 느낌이 있다.

마치 축구하러 가서 땀도 안흘리고 온 듯한 느낌

매일 조금씩 기업에 대해, 팀원 그리고 같이 일하는 방법을 알다보니,

이제는 담당 프로젝트도 생겼고, 서브 프로젝트도 생겼다

 

여기서도 알아야할 것들이 많고, 물어볼 것도 많지만,

코드를 작성하고 주체적으로 생각할 것이 생겼고,

백엔드, 디자인, PM 등 다른 팀원과 콜라보 할 수 있다는 것에 기쁘다.

 

 

 

박제 시키는 as const

타입스크립트 코드를 보다가 'as const'라는 것을 봤다

const라고 하니까 추측한 것은 값을 변하지 못하게 하는 건가?

했는데 그런 개념이었다

 

객체의 프로퍼티나 배열의 요소를 박제시키는 거다

만약 Pages라는 객체를 as const로 박제시켰다고 해보자

const Pages = {
  home: '/',
  about: '/about',
  contacts: '/contacts',
} as const;

 

그럼 Pages의 프로퍼티의 값을 변경 못한다

// ⛔️ Error: Cannot assign to 'about', because it is
// a read-only property
Pages.about = 'hello';

// ⛔️ Error: Property 'test' does not exist on type ...
Pages.test = 'hello';

 

 

store을 잘게 자르는 Redux toolkit

큰 store을 기능별로 잘게 자른다, 자른 녀석들을 slice라고 부른다

그리고 이 잘라진 slice들을 하나의 reducer로 모아주는 역할도 Redux toolkit의 역할

 

코드로 알아보자

import { createSlice, configureStore } from '@redux/toolkit';

// 카운터용 Slice를 만들어준다
const counterSlice = createSlice({
  name: 'counter',
  initialState: {value: 0},
  reducers: {
    up: (state, action) => {
      state.value = state.value + action.payload
    }
  }
})


// dispatch에서 사용할 액션을 간략하게 빼낸다
const { up } = counterSlice.actions


// store에서는 여러 reducers를 합쳐준다
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer
  }
})


// slice를 통해서 만든 up을 dispatch로 보낸다
function Couter() {
  const dispatch = useDispatch()
  const count = useSelector(state => {
    return state.counter.value
  })
  dispatch(up(2))

  return (
    // JSX 생략 
  )
}

 

 

Reudx 비동기 작업을 위한 Thunk

Redux toolkit에 있는 기능으로,

Redux의 비동기 작업을 위해 탄생한 Thunk이다.

 

비동기 코드를 넣을 수 없는건 아니다

이렇게 사용할 수도 있다

<button onClick = { async () => {
  const resp = await fetch('https://api.countapi.xyz/visits')
  const data = resp.json()
  dispatch(set(data.value))
  // 위 아래 같은 녀석
  // dispatch({ type: "counterSlice/set", payload: data.value })
}}>+ async fetch without thunk</button>

 

다만 다른데서도 필요하면 중복이 발생하고, 유지보수도 힘들다.

보기도 싫다는 이유도 있겠다.

 

생활코딩의 Thunk 영상을 두어번 봤지만 아직 어디에 사용할지 삐릿하고 안와서,

현재는 이런 컨셉만 아는 지식 상태로 놔두기로 하자

 

 

Ant Design은 onChange 대신

한 프로젝트에서 Ant Design의 Form을 사용하고 있다

Form의 변화가 있을 때 state를 Redux store로 보내주기 위해,

onChange를 사용했는데 빨간 밑줄을 그어버린다

 

Ant Design에서는 onChange 대신에 onValuesChange를 사용하라고 한다

하지만 필드 전체 내용이 필요해서 onFieldsChange를 사용했다

 

 

TypeScript에서 object 타입 사용말자

여러번 사용할 목적으로 util 폴더로 뺀 함수에서,

리턴값을 inferface로 값을 정해주기 힘드니까 타입을 object로 해줬지만 경고가 뜬다

"object로 하지마"라고. 아마도 거의 모든게 object라 그러지 않았을까 싶다

 

그래서 사용한 것은 TypeScript의 유틸리티 타입 중 하나인 Record

function changeArrToObj(arr: Array):Record<string: unknown> {
  // 배열을 객체로 바꾸는 코드 생략
  return obj
}

 

위에서 반환받는 값의 타입은 Record<string: unkown>

하지만 실제 컴포넌트에서는 정확한 값을 보여주고 싶어서 inferface를 만들기도 한다

예를 들어 이런 interface가 있으면 타입 에러를 또 띄위게 되는 거다

interface UserInfo {
  name: string;
  age: number;
}

 

이럴 때 사용할 수 있는 것이 'as'

// 앞 생략
  changeArrToObj(user as UserInfo)
// 뒤도 생략

이 말은 해당 객체를 UserInfo로 생각하라는 이야기~ 

 

 

레거시

여러 프로젝트가 존재한다.

조금 더 익숙한 스택으로 작성된 것도 있는 방면

Spring, JSP 그리고 React가 혼재된 프로젝트도 있다.

 

현재는 두 가지 프로젝트를 모두 담당하게 될 것 같다

비록 Legacy라는 별명이 붙은 친구들이지만,

새롭게 찾아 찾아 알아가는 지식들에 재미와 성취감도 생기고 있다.

 

이 친구의 특징은 Spring, JSP 그리고 React다

여기에는 아마도 내가 생각하는 최고의 배우는 방법으로 신나게 나아가자

최고의 방법: 하면서 배우기(Learn as you go)

 

 

참고 링크

Understanding 'as const' in TypeScript

=> https://bobbyhadz.com/blog/typescript-as-const

 

redux toolkit - thunk 를 이용해서 비동기 작업을 처리하는 방법

=> https://youtu.be/K-3sBc2pUJ4

 

xlsx - npm

=> https://www.npmjs.com/package/xlsx

 

Moment.js

=> https://momentjs.com/

 

OnFieldsChange - Ant Design

=> https://ant.design/components/form/#components-form-demo-global-state

 

Utility Types - TypeScript

=> https://www.typescriptlang.org/docs/handbook/utility-types.html

 

What does the "as" keyword do?

=> https://stackoverflow.com/questions/55781559/what-does-the-as-keyword-do

 

 

Sail by Dave Ruck @unsplash