Code Refactoring

박정호·2022년 8월 19일
0

Portfolio

목록 보기
3/6
post-thumbnail
post-custom-banner

🧨 중복되는 useSate, onChange

👎 Before code

  • 리팩토링 전 코드를 보면 다음과 같다. 게시글 작성 페이지에서 각각의 form에 글자를 입력하였을 때 글자가 저장되는 각각의 state가 필요했고, handler가 필요했다. handler 함수라도 통합하여 사용하려고 하나의 hanlder만 사용하려 한다면 모든 form들의 setState값이 변해버리는 현상이 발생하여 결국엔 handler함수 또한 각각 하나씩 다 작성하였다.
<studyWrite.js>
 const [Title, setTitle] = useState('')
 const [SubTitle, setSubTitle] = useState('')
 const [Category, setCategory] = useState('')

    const titleHandler = (e) => {
        setTitle(e.target.value)
    }
    const subTitleHandler = (e) => {
        setSubTitle(e.target.value)
    }
    
    const categoryHandler = (e) => {
        setCategory(e.target.value)
    }
 
    
     <Form.Control
    	type="text"
        placeholder="제목을 작성하세요"
        onChange={titleHandler} />

👍 Refactoring code

  1. inputs이라는 변수에 상태값을 넣어준다.
  2. useState의 상태값에 객체로 값이 들어간다.
  3. 그 값들을 비구조화 할당으로 나누어준다.
  4. change함수에서의 name과 value 또한 비구조화 할당으로 나누어준다.
  5. setInputs에 spread문법을 사용(직접 수정 X)하여 ...inputs(현재값)을 넣어준다.
  6. 키:값 을 이용하여 키 값이 name에 해당하는 value 값을 넣어준다.

잠깐) 비구조화

  • 배열이나 객체의 속성 혹은 값을 해체하여 그 값을 변수에 각각 담아 사용하는 자바스크립트 표현식
<studyWrite.js>
// 1,2번
const [inputs, setInputs] = useState({
        category: '',
        title: '',
        subTitle: '',
    })
    
const { category, title, subTitle } = inputs // 3번

    const onChange = (e) => {
        const { value, name } = e.target // 4번
        setInputs({ // 5번
            ...inputs,
            [name]: value, //6번
        })
    }
    
     <Form.Control
     	name="title" // 6번
        type="text"
        onChange={onChange}
          />

🤔 만약?

일반적인 방법

  • 다음과 같은 방법으로 일반적으로 값을 전달할 수 있다. 그러면 Category 컴포넌트에서도 상태값과 setState함수의 기능을 그대로 받아서 사용할 수 있다.
const [category, setCategory] = useState('카테고리 데이터');

<Category category={category} setCategory={setCategory}></Category>

궁금하다!!

위와 같이 값들을 객체 형태로 상태관리 해주는 중에, category값을 다른 컴포넌트에 props로 전달해야 한다면???
-> 내 상식 선에서 생각해본 코드는 대충 다음과 같다.

const [inputs, setInputs] = useState({
        ...
        category: '',
        ...
    })
const { category, title, subTitle } = inputs
const setInputs(()=>{...inputs.category })

<Category category={inputs.category} setCategory={setInputs}></Category>

-> 하지만 props 전달 방법에 대해서는 찾지 못했고, 생각해낸 다른 한가지는 redux를 이용하여 전역 store값으로 전달하여 Category에서 그 값을 가져다 쓰는 것이다. 하지만, 배보다 배꼽이 더 큰 꼴이 나서 더욱 코드만 길어질 뿐인 것 같다. 그래서 일단 위와 같은 상황에서는 일반적인 useSate를 사용하여 코드를 구현한 바가 있다...

참조:
비구조화 할당
https://learnjs.vlpt.us/useful/06-destructuring.html
useState 여러개 관리하기
https://crispypotato.tistory.com/150

🧨 barrel structure & 절대 경로

👎 Before code

  • 이 전에는 해당 페이지에 필요한 컴포넌트들을 각각 위치한 경로애서 가져와야 했고, 그 경로를 입력하는 가운데 상대경로로 표시하였다.

잠깐) 상대경로

  • 상대경로는 현재 위치를 가장 중요하게 여기는 기준으로 삼고 목적지까지의 상대적인 경로를 뜻.

    참조: https://mollangpiu.tistory.com/222

1️⃣ 문제 1.

현재 페이지에서 멀리 떨어져있는 위치의 폴더의 컴포넌트를 가져다 쓰기 위해서는 ../ 지옥이 시작된다.
변경전)

import Footer from '../../components/common/Footer/footer'

2️⃣ 문제 2.

또한, 같은 폴더 위치의 컴포넌트들을 사용하려면 각각의 경로에 맞춰서 하나씩 불러와야 했다.
변경전)

import Footer from '../../components/common/Footer/footer'
import Header from '../../components/common/Header/Header'
import Modal from '../../components/common/Modal/Modal'

👍 Refactoring code

1️⃣ 문제 1 해결.

  • 상대경로가 아닌 절대경로를 사용하자.

잠깐) 절대경로

  • 처음부터 시작하여 목적지까지의 절대적인 경로를 의미합니다. 시작 지점부터 목표지점까지의 어느 누가 봐도 절대적으로 이곳을 가리킬 수 있는 곳
  • CRA 프로젝트의 root에 jsconfig.json을 생성하고 코드를 작성한다.
{
  "compilerOptions": {
    "baseUrl": "src"
  }
}

잠깐) jsconfig.json

  • '이 파일이 존재한다면, 이 파일이 위치한 이 곳이 바로 루트 디렉토리다' 라고 알려주는 역할을 한다.
  • 소스파일들을 일괄적으로 어떻게 해석하고 처리하는 지에 대해서도 명시하는 파일
  • 따라서 이렇게 변하게 된다.
    변경후)
import Footer from 'component/common'

참조: https://basemenks.tistory.com/266

2️⃣ 문제 2 해결.

  • index.js를 생성하자.
    -> 각각의 폴더에 index.js를 만들어서 depth를 얕게 만들어준다.

만약 components 폴더에 모달,헤더,푸터 등의 컴포넌트들이 존재한다. components 폴더에 index.js를 만들어서 다음과 같이 코드를 작성한다. 그러면 해당 페이지에서는 각각의 컴포넌트가 있는 경로까지 찾아가지 않고 한꺼번에 묶여있는 컴포넌트들을 꺼내다 쓰면 되는 방식이다. index.js에서 직접적으로 가져다 쓰는 방식이라기보다, index.js를 생성하면 node가 실제 경로를 찾을 때 index.js를 찾기 때문에 자동적으로 import 되어진다고 할 수 있다.

export {default as LoginRecordHeader} from  './Header/loginRecordHeader/loginRecordHeader'
export {default as Header} from  './Header/mainHeader/header'
export {default as Footer} from  './Footer/footer'

export {default as Modal} from './Modal/modal'
export {default as Pagination} from './Pagination/pagination'
export {default as Slide} from './Slide/slide'
export {default as TextEditor} from './TextEditor/textEditor'
  • 따라서 이렇게 변하게 된다.
    변경후)
import {Footer,Header,Modal} from 'component/common'

! index.js를 추가하는 방식을 barrel이라고 부르는 듯.

📃 전체코드

변경 전

변경 후

참조: https://velog.io/@rimo09/React%EC%97%90%EC%84%9C-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EA%B2%BD%EB%A1%9C-%EA%B9%94%EB%81%94%ED%9E%88-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)
post-custom-banner

0개의 댓글