Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 리팩토링 #195

Open
BEOKS opened this issue Feb 24, 2022 · 6 comments
Open

React 리팩토링 #195

BEOKS opened this issue Feb 24, 2022 · 6 comments
Assignees
Labels
FrontEnd FrontEnd Refactor Code refactoring

Comments

@BEOKS
Copy link
Owner

BEOKS commented Feb 24, 2022

Props to React-Redux

현재 코드는 state가 계층형으로 이루어져 있기 때문에, 상위 state를 가져오는데 코드 작성이 많이 필요하고 state 변화에 따라 필요없는 Component 갱신이 발생하고 있다. 이에 따라 Redux를 이용해서 State를 Store에서 전역변수처럼 관리하도록 하여 이 문제를 해결하고 패키지 아키텍쳐를 리팩토링하여 새로운 기능을 추가할 때 더욱 수월하게 진행하기 위한 토대를 마련해야 할 필요가 있다.

@BEOKS BEOKS added FrontEnd FrontEnd Refactor Code refactoring labels Feb 24, 2022
@BEOKS BEOKS changed the title React - Redux로 리팩토링 React 리팩토링 Feb 24, 2022
@BEOKS
Copy link
Owner Author

BEOKS commented Feb 24, 2022

Typescript

현재는 완전한 다이나믹 타이핑인 Javascript를 사용하고 있는데, 어플리케이션의 규모가 커지면서 변수의 타입이 애매해져 활용하는데 어려움이 있다. 예를 들어, 아래와 같은 state를 재활용하고 싶은데 projectInfoLists의 형식이 기억나지 않아서 활용하려면 이 변수가 어떤 형식을 가지는지 직접 돌려봐야 한다.

export default function Page() {
    const [drawerOpenStatus, setDrawerOpenStatus] = React.useState(false);
    const [projectInfoLists, setProjectInfoLists] = React.useState([]);
    const [invitedProjects, setInvitedProjects] = React.useState([]);
...

이런 경우를 방지하고 컴파일 타임에 에러를 미리 잡기 위해서 타입스크립트를 사용하려고 한다.
그러나 현재 props로 인해서 상태 변수가 상당히 분포되어 있으므로 먼저 typescript로 변환하여 변수 타입을 지정하는 것은 옳지 않으므로 redux 리팩토링을 완료한 후, 진행한다.

@BEOKS
Copy link
Owner Author

BEOKS commented Mar 15, 2022

@doheez
Copy link
Collaborator

doheez commented Mar 22, 2022

@BEOKS 선배 나 리덕스 공부하다가 혼란이 왔는데
많은 사람들이 action을

{ type: value1, payload: value2 }

이런 형태의 object로 정의하더라고
그런데 선배는 action을

(value2) => ({ type: value1, payload: value2 })

이렇게 function으로 정의했잖아

  1. 이렇게 쓴 이유가 component에서 dispatch에 action을 기재할 때
    payload를 인자로 넘겨주기 위함이야?

  2. component에서 state를 변경하고자 할 때
    payload를 사용하지 않고 단순히 reducer에서 정한 특정 값으로 변경할 경우엔
    action을 굳이 함수 형태로 적어줄 필요는 없는 거야?

@BEOKS
Copy link
Owner Author

BEOKS commented Mar 22, 2022

이렇게 쓴 이유가 component에서 dispatch에 action을 기재할 때
payload를 인자로 넘겨주기 위함이야?

A. 정답! 그럼 action을 호출할 때 결국 데이터가 담긴 object를 dispatch에 리턴하게 되니까 그런식으로 작성하는 편이야.
dispatch({type : "BLA_BLA", payload : data}) 같은 식으로 선언해도 상관없지만 이러면 내부 타입이 밖으로 들어나서 나중에 코드를 일일이 수정해야하는 경우가 생기거든

component에서 state를 변경하고자 할 때
payload를 사용하지 않고 단순히 reducer에서 정한 특정 값으로 변경할 경우엔
action을 굳이 함수 형태로 적어줄 필요는 없는 거야?

A. 문법적으로 보면 굳이 함수 형태로 해줄 필요는 없어, 그런데 일관성이 없어서 다른 개발자들한테 혼동을 줄 수 있어.
예를 들어서 이미 작성한 DialogAction의 일부를 보자.

const DialogAction={
    openDialog : ()=>({type: TYPE.OPEN_DIALOG}),
    setColumnList : (columnList : string[])=>({type : TYPE.SET_COLUMN_LIST, payload : columnList}),
}

여기에는 payload를 사용하지 않는 action과 사용하는 action이 있어 이 두 개를 dispatch에서 사용할 때는 아래처럼 호출하겠지?

dispatch(DialogAction.openDialog())
dispatch(DialogAction.setColumnList("a,b,c,d"))

이 경우 둘 다 함수형 형태로 호출해서 일관성 있는 문법을 제공해 그런데 만약 payload를 사용하지 않는 openDialog에서 함수 형태를 사용하지 말고 아래처럼 바로 object를 리턴한다고 생각해보자.

const DialogAction={
    openDialog : {type: TYPE.OPEN_DIALOG},
    setColumnList : (columnList : string[])=>({type : TYPE.SET_COLUMN_LIST, payload : columnList}),
}

그럼 다른 개발자들은 DialogAction은 전부 함수형태로 정의되어 있다고 생각해서 아래 처럼 호출하면 에러가 발생하는 경우가 생겨

dispatch(DialogAction.openDialog()) //error
dispatch(DialogAction.setColumnList("a,b,c,d"))

요약하자면, payload를 사용하는 경우 함수 형태를 사용해야 하는데 그렇다고 payload를 사용하지 않는 경우를 함수 형태로 선언하지 않으면 일관성이 깨져서 내부 코드를 모르는 다른 개발자들한테 혼동을 줄 수 있고 결국 에러가 발생함으로 굳이 object로 바꿀 필요는 없어

@doheez
Copy link
Collaborator

doheez commented Mar 22, 2022

덕분에 완벽하게 이해했어 정성스러운 설명 고마워!!
그리고 질문이 하나 더 있는데 reducer에서 action의 이름을 정의할 때

export const TYPE={
    SET_DIALOG_OPEN : `${HEADER}/SET_DIALOG_OPEN` as const,
}

와 같이 literal type으로 const assertion하는 이유가 뭐야?

action의 이름에 헤더를 사용해서 이미 해당 reducer 파일명까지 적어줬기 때문에
as const를 쓰지 않고 string type으로 둔다고 해도
다른 reducer에서 사용하는 action과 혼동이 생길 것 같지는 않은데 왜 저렇게 적는 건지 궁금해

@BEOKS
Copy link
Owner Author

BEOKS commented Mar 23, 2022

action의 이름에 헤더를 사용해서 이미 해당 reducer 파일명까지 적어줬기 때문에
as const를 쓰지 않고 string type으로 둔다고 해도
다른 reducer에서 사용하는 action과 혼동이 생길 것 같지는 않은데 왜 저렇게 적는 건지 궁금해

as const는 값의 재할당을 막기 위해서 설정한 키워드야. 만약 재할당을 막지않으면 버그가 생길 수 있는데 이것도 예시를 들어줄게. 만약 아래와 같이 두 가지 타입이 있는데 재할당을 막지 않았다고 하자. 그리고 다른 개발자가 고의 또는 실수로 아래처럼 원래 타입에 새로운 값을 재할당한다고 하자.

export const TYPE={
    SET_DIALOG_OPEN : `${HEADER}/SET_DIALOG_OPEN` 
    SET_DIALOG_CLOSE :  `${HEADER}/SET_DIALOG_CLOSE`,
}
const DialogAction={
    openDialog : ()=>({type: TYPE.OPEN_DIALOG}),
    closeDialog : ()=>({type: TYPE.SET_DIALOG_CLOSE}),
}

//다른 곳에서 개발하다...
TYPE.SET_DIALOG_OPEN = `${HEADER}/SET_DIALOG_CLOSE`

그럼 재할당 코드가 처리된 이후에는 openDialog() 메서드를 호출해도 다이얼로그가 닫히는 현상이 발생해, 즉 TYPE의 변경으로 인해서 action이 의도대로 작동되지 않는 경우가 생기기 때문에 as const로 재할당을 막는거야. 비슷한 이유로 as const 대신 Enum을 사용하기도 하는데 Enum은 as const 보다 오버헤드가 크기 때문에 나는 as const로 작성한거야

doheez added a commit that referenced this issue May 26, 2022
프로젝트 드로어에서 스타일링 컴포넌트와 프로젝트 생성 다이얼로그 컴포넌트를 분리합니다.

Task: #195
doheez added a commit that referenced this issue May 26, 2022
프로젝트 드로어를 타입스크립트로 리팩토링합니다.

Task: #195
doheez added a commit that referenced this issue May 26, 2022
리팩토링 진행 전 테이블에서 사용했지만
지금은 사용하지 않는 유틸 파일을 삭제합니다.

Task: #195
doheez added a commit that referenced this issue May 28, 2022
"현재 선택된 프로젝트가 없습니다."라는 기본 프로젝트 이름을 삭제하고
초기값을 undefined로 변경합니다.

Task: #195
doheez added a commit that referenced this issue May 28, 2022
openDrawer -> openProjectDrawer
closeDrawer -> closeProjectDrawer

Task: #195
doheez added a commit that referenced this issue May 28, 2022
getMetaData의 인자로 dispatch 대신 콜백 함수를 넘겨주어
다양한 상황에 유연하게 대처할 수 있도록 합니다.

Task: #195
doheez added a commit that referenced this issue May 28, 2022
사용하지 않는 props를 삭제합니다.

Task: #195
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FrontEnd FrontEnd Refactor Code refactoring
Projects
None yet
Development

No branches or pull requests

2 participants