본문 바로가기
Tech/React

react 리뷰 정리

by egas 2021. 6. 15.

1. 제어 컴포넌트를 권장한다는 의미는 비제어 컴포넌트로 구현이 가능하더라도 제어 컴포넌트를 권장한다는 말이다. 컴포넌트가 데이터(상태)를 명확히 알고 관리하고 있을 때 밸리데이션을 추가하기도 쉽고 여러모로 컴포넌트의 동작이 더욱 쉽게 예측 가능해 진다.

onSubmit(event) {
    event.preventDefault();
    
    const payment = Number(event.target.elements["purchase-input"].value);

제어 컴포넌트를 쓰면 위 코드 부분이 더욱 간결해질 수 있다. onSubmit 뿐만 아니라 다른 메서드에서 payment 값이 필요 할 수도 있는데 이에 대응하기도 쉬워진다.

 

2. Context API와 같은 event bus가 필요한 프로젝트인가? 항상 오버엔지니어링은 아닌가 생각해보자. prop-drilling와 비교해서 얻을 수 있는 이점이 있는지. Context API로 인해 props 등의 shallow copy가 먹지않기 때문에 렌더링 상에서도 상태 하나가 변경되면 모든 것들이 리프래시 될 것 같다.

 

3. React는 컴포넌트가 리렌더링될 때까지 `this.state.count`를 갱신하지 않기 때문에, 이전 state 값을 기준으로 값을 계산해야 한다면 객체 대신 updater 함수를 전달해야 한다.

 

setState 는 이벤트 핸들러 내에서 비동기적이다.

setState는 일반적으로 비동기로 작동하며, 동기적으로 작동하기 위해서는 setState의 인수로 리액트에서 요구하는 함수를 할당해야 한다. 만약, 부모 자식이 모두 click 이벤트에서 setState를 호출한다면 자식은 두 번 렌더링되지 않는다. 대신 React는 브라우저 이벤트가 끝날 시점에 state를 일괄적으로 업데이트 한다. 이는 더 큰 규모의 앱에서 뚜렷한 성능 향상을 만들어낸다.

 

  • state는 직접 수정하면 안된다. 리액트는 얇은 비교를 통해 state가 변경되었는지 검사하기 때문에 직접 수정하게 되면 state가 변경되었는지 알지 못한다. 따라서 리액트에서 제공하는 setState 메서드를 사용해야 하며, 불변성을 유지해야 한다.
  • props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위한 수단이다.
  • props는 읽기 전용이다. 따라서 props가 변경되어야 한다면 렌더링을 수행한다.

 

4. style 부분, 레이아웃 부분, 비즈니스 코드 부분을 적절히 분리하자.

컨테이너(containers) 역할을 하는 컴포넌트와 재사용 가능한(shared) 컴포넌트를 분리하는 방향으로 폴더 구조를 변경해보자.

 

5. 실제 운영 프로덕션에 들어간다고 가정했을때, 현제 프로젝트에서 css-in-js가 오버 엔지니어링이 아닌지 생각하자. (오버엔지니어링은 프로젝트의 구조를 복잡하게 만드는 것)

 

6. inline css는 지양하자. ( 스타일 파일로 분리가 되어있다면 해당 이름만 갖고도 해당 레이아웃 스타일을 바로 수정할 수 있다. )

 

7. 왠만하면 전역 변수를 지정하지 말고 App 내부에서 로직적인 부분에 변수를 선언하자. 만약 전역적으로 사용되는 친구라면 constant로 빼서 사용하자.

 

8. 리액트에서 컴포넌트는 뷰 컴포넌트를 말한다. Display보다 Container를 사용하자.

 

9. key에는 고유 문자열을 넣는게 훨씬 좋다. 또한 해당 부분은 리액트 가이드에서 권장하는 부분이다.

https://ko.reactjs.org/docs/lists-and-keys.html#keys

 

리스트와 Key – React

A JavaScript library for building user interfaces

ko.reactjs.org

0,1,2,3 등의 ordered number라면, 고유한 문자열은 아니기 때문에 순서가 변경되었을때 렌더링이 안되거나, 여러 depth가 섞였을 때 대응되지 못하는 문제가 있을 수 있다.

 

10. Container Component와 Presentational Component

 

11. 리액트는 여러 부분을 최적화하고있습니다. 리액트는 내부적으로 document node에 이벤트를 delegation 합니다. 때문에 특수한 경우가 아니라면 이런 부분을 성능으로 신경쓰지 않아도 됩니다.! (17버전 이후부터는 app root component)

https://bigbinary.com/blog/react-17-delegates-events-to-root-instead-of-document

 

React 17 delegates events to root instead of document | BigBinary Blog

React 17 delegates events to root instead of document

bigbinary.com

 

12. state lifting

https://reactjs.org/docs/lifting-state-up.html

 

Lifting State Up – React

A JavaScript library for building user interfaces

reactjs.org

 

13. onChange이벤트를 <input>에 각각 걸지 않고, <form>에 한 번만 걸어도 의도한 대로 작동한다.

 

form으로 묶어서 탭을 눌렀을 때 다음 input으로 넘어가거나 하는 처리가 필요하므로 (웹 접근성 측면에서) 필요한 부분이 있다면 form을 사용해도 좋다. 쉽게 컨트롤 할 수 있냐 없냐를 생각하며 적용하면 된다.

 

14. 사실 컴포넌트라 하면, 레이아웃을 표현하기 위한 수단이기도 하지만, 수많은 사람들과 협업을 쉽게 할 수 있는 역할도 존재한다. Hierarchy의 경우에는 더더욱 그렇다. 진입점이 쉬워야 개발의 생산성이 높아지고 격리가 잘 되어 있어야 추후 구조가 변경되거나 프로젝트의 방향성이 바뀔 때 쉽게 바꿀 수 있다. 

 

진입점과 컴포넌트의 depth level이 동일하다. 어떤 코드에 비즈니스 로직이 들어있고 컨트롤러의 역할을 담당하는지. 공통 컴포넌트는 어떻게 관리할지 생각해보자. 폴더 기반으로 구축해보자. 또한 폴더부분으로 감싸면 유닛테스트 파일도 폴더내에 제공할 수 있으므로 좋다.

 

15. 전반적으로 배열 조작, parameter에 대한 예외처리 로직을 잘 고려하자. 어느 부분에서 인덱스를 기반으로 배열에 접근한다면 접근하는 부분에서 js는 에러를 뿜게 되며, 심한 상황에서는 어플리케이션이 오동작 할 수 있다. 이런 문제는 대다수가  parameter를 넘기거나 배열을 조작하는 부분에서 생긴다. 

 

16. CSS Modules을 사용하자.

 

17. const price = event.target.price.value; 에서constprice=event.target.price.value || 0;으로 예외처리를 했다면 조금 더 좋지 않았을까.

 

18. 다음과 같이 컴포넌트를 하나로 묶어서 import할 때 편하게 하자.

index.js
export {default as Main} from "./Main"
export {default as LottoItem} from "./LottoItem"
export {default as LotteryCountDown} from "./LotteryCountDown"

쓰는쪽
import {Main, LottoItem, LotteryCountDown } from './components/Main';

 

19. isDuplicate 보다는 hasDuplicatedItem 네이밍이 더 좋다.

 

20. 컴포넌트는 props와 state를 관리하여 화면에 보여지는 UI를 담당하는 기본 단위, 안에 들어가는 함수들도 정의에 맞춰서 분리시키자.

 

21. 반환값이 명시적인 ternary operator를 사용하여 조건부 렌더링을 해주자. (Short-circuit Evaluation)

{isOkay ? (
  <>
    <Test1 />
    <Test2 />
  </>
) : null}

 

22. 리액트에서 리스트를 만들 때 고유한 key를 설정하도록 강제하는 이유는 배열의 요소 추가, 수정, 삭제에 효율적으로 대응하기 위함이다.

  • 효율성 측면
    • 예시: [a b c] 리스트에서 a를 삭제하여 [b c] 를 렌더할 경우,
    • 문제: key값을 주지 않으면 a자리에 b를, b자리에 c를, c자리에는 아무것도 렌더하지 않는 번거로운 작업이 필요합니다.
      (key값을 주면 [a b c]에서 바로 a만 key값으로 잡아와서 빠르게 삭제할 수 있다.
  • 데이터 맵핑 측면
    • 예시: [a b c] 리스트에서 a앞에 z를 추가하여 [z a b c] 를 렌더할 경우,
    • 문제: key값을 주지 않으면 리액트는 index를 default key값으로 활용하는데 이는 a(기존 index 0)가 가지고 있던 데이터가 z(새로운 index 0)에 맵핑되어 버린다.(참고한 글)

두 가지 측면을 모두 생각해보았을 때 고유한 key값을 가져야 한다는 의미는 배열 내 형제끼리 중복되지만 않으면 된다라는 것 뿐만 아니라, 리렌더 되었을 때도 자신만의 고유한 key를 유지할 있어야 한다는 의미다. index를 순차적으로 변환해서 'a', 'b', 'c', ...를 key값으로 주는 방식은 위의 데이터 맵핑이 꼬이는 문제를 전혀 해결할 수 없다. 따라서 개별적 특성을 갖는 id를 생성해주어야한다.

 

하지만, 리스트가 변하지 않고 정적일 것이 보장(재정렬, 필터되지 않음)되는 경우는 index를 key로 사용해도 괜찮다.

 

23. 혁명...

    const { className, onClick, text } = this.props;
    return (
      <button type="button" className={`PlainButton ${className}`} onClick={onClick}>
        {text}
      </button>
    );
    
    const { className, text, ...props } = this.props;
    return (
      <button type="button" className={`PlainButton ${className}`} {...props}>
        {text}
      </button>
    );

 

24. 스타일링은 class로 제어한다 + BEM이라는 규칙으로 네이밍하자.

<input id="toggle-button"

http://getbem.com/naming/

 

BEM — Block Element Modifier

BEM is a highly useful, powerful, and simple naming convention that makes your front-end code easier to read and understand, easier to work with, easier to scale, more robust and explicit, and a lot more strict.

getbem.com

https://github.com/airbnb/css#oocss-and-bem

 

airbnb/css

A mostly reasonable approach to CSS and Sass. Contribute to airbnb/css development by creating an account on GitHub.

github.com

 

25. 객체 지향의 책임과 역할을 공부하자.

 

26. 최고의 공부는 잘 만들어진 오픈소스 공부

https://chakra-ui.com/docs/form/button

 

Chakra UI - A simple, modular and accessible component library that gives you the building blocks you need to build your React a

Simple, Modular and Accessible UI Components for your React Applications. Built with Styled System

chakra-ui.com

 

27. padStart() 빌트인 메소드가 우리에게 있다.

 

28. children을 통째로 받는건 어떨까?

    const { className, disabled, text } = this.props;
    return (
      <button type="submit" className={`SubmitButton ${className}`} disabled={disabled}>
        {text}
      </button>
      
    const { className, disabled, children } = this.props;
    return (
      <button type="submit" className={`SubmitButton ${className}`} disabled={disabled}>
        {children}
      </button>

 

29. 높은 응집도 + 낮은 결합도!

 

30. early return 오.. 단어정립.. 메모.

render() {
  // state가 없으면 바로 리턴
  if (!this.props.location.state) return <Redirect to="/" />

  // 이 아래는 state가 무조건 있음.
}

 

31. Array.from()

Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.

 

32. webpack이외에 snowpack이라는 번들러가 존재한다는 사실을 알았다.

 

33. Props로 하여금 컴포넌트간의 의존성을 느슨하게 갖기위한 방책은 IoCDependency Injection 패턴입니다. DI를 조금 더 공부하시면 좋을 것 같고, 보통 이러한 처리를 위해 Container & Presentational 이라는 패턴이 존재했고, Function Component에서는 hooks로 이런 패턴을 더 쉽게 개발할 수 있게 제공합니다. Dan Abramov 가 제시한 하나의 방책이다.

 

Dependency injection - Wikipedia

In software engineering, dependency injection is a technique in which an object receives other objects that it depends on. These other objects are called dependencies. In the typical "using" relationship the receiving object is called a client and the pass

en.wikipedia.org

 

34. ref를 사용하는 부분은 다양하다 :) 메모리 상에서 캐싱을 하기 위해 쓰기도 하고, 컴포넌트 단위에서 controlled와 uncontrolled 를 이용하기 위해 사용하기도 하고, focus등의 이벤트를 주기 위해 사용하기도 한다.

 

35. <input type="number"/> 를 통해 number type이 들어올 것이라는 걸 보증하는데도 예외처리를 해주어야할까?

number type은 render를 해주는 함수에서에서 알고 있는 정보이고, isValidPayment에선 알 수 없는 정보이다. isValidPayment는 value에 대해서 number로 가져올거라는 가정을 알기위해 render 함수를 참조해서 보아야한다. 이 부분은 언제든지 정책이 변경될 수 있는 부분으로 보이고 그렇다면 render 쪽도 수정을 해줘야하고 isValidPayment도 수정을 해줘야한다. 타입스크립트가 필요한 이유중 하나.

 

36. ref를 되도록이면 안쓰는게 좋다.

=> ref에서 current를 접근해 직접 수정을 한다면, react에서 제공하는 life cycle 혹은 V-DOM 렌더링 뎁스가 꼬일 위험이 굉장히 높다.

또한 ref를 여기저기서 호출하면 어디에서 로직이 수정되었는지 추적이 어려워진다.  ref는 side-effect가 존재합니다. (current가 undefined 이거나.. 등등) 그리고 대다수의 경우는 react lifecycle을 따르는게 좋고, lifecycle로 해결이 되는 부분들이다.

 

37. 타입스크립트에서는 

this.state.winningNumbers.map((_, index) => (

의 코드를 아래와 같이 작성 가능하다.

this.state.winningNumbers.map((, index) => (

 

38. 768 같은 반응형 대응 코드는 variable로 관리하자.

@media screen and (max-width: 768px) {

 

39. htmlFor 속성대신 label 안에 input 을 넣으면 id 관리할 필요없이 포커싱이 된다.

 

40. 데이터를 초기화하기 위한 좋은 방법을 생각하기 이전에, 더 중요하게 먼저 알아야 하는것은 컴포넌트의 '관심사' 입니다.
PaymentForm이라는 컴포넌트를 만들기로 했다면 이 컴포넌트의 관심사(무엇을 알고 처리하며 무엇을 몰라도 되는가 혹은 몰라야 하는가)가 무엇인지에 따라 적절한 책임을 부여하고 책임에 따른 경계를 명확히 해야한다.

 

41. display로 제어하지 않은 이유가 있을까?

화면에 보이지 않는데 왜 화면 상에 영역을 차지하고 있는게 맞는 건가요?
단순히 opacity transition 때문이라면 올바르지 않은 것 같다.

 

42. Single Source of truth 원칙을 지키자.

 

43. typescript 메서드 리턴 타입, 변수 타입 명시 불필요한 부분 제거 
: 대부분의 경우 타입스크립트는 함수가 반환하는 타입을 자동으로 확인하여 설정하여 주기때문
: (메서드를 실행해 받아오는) 변수의 타입도 명시 필요 없음
: 커서 올려보면 다 타입이 표기된다.

 

44. type vs interface : 지금 적용하신 type alias 부분이 과연 적절하게 기술적 선정이 된 걸까요? type과 interface의 차이는 뭐고, props등의 영역에서 type을 쓸 지 interface를 쓸 지 고민해보자.  링크 👍

 

45. &&연산자의 경우 앞의 값이 false, null, undefined, ''(빈 스트링) 이면 화면에 나타나지 않는다. 다만, 앞의 값이 0으로 평가되면 화면에 나타난다.

https://reactjs.org/docs/jsx-in-depth.html#booleans-null-and-undefined-are-ignored

 

JSX In Depth – React

A JavaScript library for building user interfaces

reactjs.org

 

46. useRef

  • DOM element를 조작하는 경우가 아닐 때에도 사용한다
  • 컴포넌트의 전 생애주기를 통해 유지되는 값에 사용한다. useRef로 관리하는 변수는 값이 바뀌어도 컴포넌트가 리렌더되지 않는다
  • useRef는 .current 프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같습니다
  • https://ko.reactjs.org/docs/hooks-reference.html#useref
 

Hooks API Reference – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

47. useInterval 이라는 custom hook으로 분리해서 만들어보자. 범용적으로 자주 사용되는 hook이다.

 

48. Hooks

  • Hooks가 나오기 전에는 Function 컴포넌트에서 상태를 가질 수 없었기 때문에 상태를 가지지 않는 컴포넌트만 Function 컴포넌트로 만들 수 있었다. 하지만 Hooks가 등장하면서 Function 컴포넌트에서도 상태와 생명주기를 사용할 수 있게 되었고, this 바인딩과 같은 복잡한 절차를 이해하지 않아도 되는 Function 컴포넌트가 많이 쓰이게 되었다.

49. react function component에서 hooks를 구현하기위해 hooks에 대한 이벤트를 저장하는 state heap이 있어서 동기적인 실행이 된다.

 

50. onClick={() => func()} 형태가 보이는데, onClick={func} 만으로 안되는 이유가 있나요?

굳이 필요한 경우가 아니라면 후자를 쓰자.

 

51. 동적할당 한 친구는 모던 브라우저가 알아서 잘 해제 해 주겠지만. 구버전 브라우저는 혹시 모르니 링크를 참고해 해제해주도록 합시다.

 

52. day.js와 같은 라이브러리를 이용해보자.

 

53. React.Portal 로 모달 컴포넌트를 만들어보자.

 

54. 웹 표준에 지키기(Main 컴포넌트 -> MainSection 컴포넌트)

 

55. 웹 접근성 기능 추가(아이콘만 있는 버튼에 보이지 않는 이름 부여)

 

56. Atomic Design

atom은 그렇다 치고 molcules(?), organism (?) 이 두 단계가 의미없다고 생각해서 좋아하지 않습니다.
실제로 프로덕트를 만들다 보면 atom, molcules, organism 이렇게 세 단계로 딱 떨어지지 않습니다.
그런데 이런 상황에서 우리는 atomic design을 적용했고 이걸 지켜야해! 하는 순간 구조가 망가지고 제어가 역전되는 상황이 발생한다.

 

인터뷰에서도 atomic design을 적용하신 분이 계셔서 여쭤보면 molcules, organism 이 두 가지에 대한 구분이 사람마다 달라 혼란을 겪었다는 이야기도 많이 듣습니다.

 

그럼에도 왜 atomic design을 적용하나? 하는 부분이 있는데, 그건 복잡한 컴포넌트를 어떻게 추상화할지 고민할 시간에 정해진 규약에 쑤셔넣자? 정도로 이해하고 있습니다 ㅎㅎ

 

57. eventHandler 는 handle~ 혹은 onClick~ 같이 구분할 수 있는 prefix를 붙여주자.

 

58. useReducer의 재발견

 const [isToggleOn, setToggle] = useState(false);
 
 const [isOn, toggle] = useReducer(prev => !prev, false);

 

59. 한번만쓰일것같은데 꼭 함수로 분리해야할까요? 👀

 

60. React Component props 에는 children도 있답니다!

const Button = (props) => <Styled.Button {...props}>{props.children}</Styled.Button>;
const Button = (props) => <Styled.Button {...props}></Styled.Button>;

이렇게 작성해도 똑같다는 뜻이지요! 👍

 

61. interface와 type 의 다른점은 무엇일까요? 왜 type에서 interface로 바꾸셨나요? 👀

  1. 위 문서를 보니 ts에서는 interface사용을 권장하고 있습니다. 많은 ts 유저들이 위 방식을 따를 것이라 판단해 다른 이들이 제 코드를 볼 때 가독성, 추후 ts 프로젝트에서 협업 시 코드 스타일 차이를 줄이기 위해 변경한 것이 첫 번째이유입니다.
  2. 에러메시지가 더 상세하게 나옵니다.
  3. 다른 차이로 inteface는 확장에 열려있고, type은 닫혀있습니다.

 type alias같은 경우에는 union 혹은 tuple이 있는 경우에 사용하는게 맞아보이며, interface라는 이미 수십년에 걸쳐 만들어진 객체지향의 개념을 대체할 것으로 보이지 않는다.

type같은 경우에는 export로 선언되었을 때, (전역적으로 사용되는 곳에서) 이름이 같으면 빌드상에 원하는 결과값이 안나오는 문제가 있다.

 

62. React.FC, React.VFC란 무엇일까.

 

63. 크게 계산하는 로직이 있다면 useCallback을 사용해서 함수를 래핑하는게 좋고, useMemo의 경우에는 자주 렌더링 되는 컴포넌트의 경우에 사용이 되는데, useMemo를 크게 권하지 않는다. 공식문서에서도 그렇지만, 최대한 없이 사용하면서 최적화를 진행하고, 최적화가 필요할 때 (적어도 로또에서는 없어보입니다) useMemo를 사용하는 편이 좋다. 무조껀 적으로 추가하면 오히려 성능이 약화되는 문제가 생길 것이다.

 

64.

함수 컴포넌트 같은 경우에는 React.FC를 붙여주시는 게 좋고

저는 이 리뷰에 동의할 수가 없는데요, FC 타입은 암묵적으로 children을 props에 포함시킵니다. 합성을 의도하지 않는 컴포넌트도 합성 대상이 될 수 있고 컴포넌트에서 가장 중요하다고 생각되는 props design에 암묵적인 property가 포함되는 것이라고 생각합니다.

Props는 필요한 부분만 별도로 정의하고 parameter에 선언해주는 것이 좋다고 생각합니다.

cra typescript template에서는 React.FC 타입을 제거했습니다 (facebook/create-react-app#8177)

 

  1. 일단 React.FC 타입으로 컴포넌트의 타입을 명시하면 실제로 함수 컴포넌트에서 children을 받든 안 받든 children을 넘길 수 있게 됩니다. 즉, 컴포넌트에 대한 잘못된 타이핑인 것입니다.
  2. 그리고 애초에 React.FC 타입이 children을 제공하는 것은 의도된 것이 아니라 호환성을 위해 남겨진 것입니다. (SFC)

children을 제공하는 컴포넌트의 경우에는 다음 두가지로 Props를 정의해야 할 수 있고 이 방법을 사용하는 것이 더 좋습니다.

 

interface Props {
  children: React.ReactNode
}
type Props = PropsWithChildren<P>

아래는 관련 타입과 관련된 논의가 이루어진 이슈입니다. 🙇

cc. DefinitelyTyped/DefinitelyTyped#33602

 

[@types/react] Enable passing children down to "ExoticComponent"s by raon0211 · Pull Request #33602 · DefinitelyTyped/Definite

The definition of ExoticComponent

is as follows: (please refer to the introduction of ExoticComponent to #30054) interface ExoticComponent

{ (props: P): ReactElement | nu...

github.com

 

---

근데 요새는 React.FC도 사용하지 않는게 흐름인 것 같아요(https://fettblog.eu/typescript-react-why-i-dont-use-react-fc/). children이 필요할 때만 WithChildren으로 prop interface를 감싸주는 정도로 사용하면 되는데, 웬만하면 children대신 props로 값을 넘기기 때문에 그런 경우도 잘 없습니다.

 

65. react에서 reset할 필요없다. 다시 mount하자.

 

Lotto Component를 추출하여 key를 변경하는 방법

App Component의 바로 밑에 바로 구매금액 입력란, 당첨번호 입력란 등의 Component가 있는데,

App Component와 다른 Component 사이에 Lotto Component를 위치시킨 후,

다시 시작하기 버튼을 누르면 Lotto Component의 key를 변경하게 하여 Lotto Component를 다시 mount시켜,

Lotto의 상태를 초기화시켰다.

 

66. createRef useRef의 차이점

  • createRef: 클래스 컴포넌트에서 사용 (리액트 16.3버전에 추가)
  • useRef: 함수 컴포넌트에서 사용 (리액트 16.8버전에 추가)

함수 컴포넌트에서 createRef를 사용하려고 하면 사용할 수는 있지만(?) hook이 아니라서 상태를 가질 수 없다. 즉 컴포넌트(함수)가 다시 호출될 때마다 초기화된다.

 

67. 스타일드를 사용하셨으니 스타일드 컴포넌트를 기반으로 하는

등의 라이브러리들이 컴포넌트 네이밍과 구조를 어떻게 가져가는지 썬의 코드와 비교해보시는걸 추천드립니다!

 

68. Children 활용

지금보다 더 Children을 활용을 높이면 상태관리나 컴포넌트 계층 관리가 용이할 것이라고 생각이 듭니다.

 

69. https://github.com/qkraudghgh/clean-code-javascript-ko#%EC%A1%B0%EA%B1%B4%EB%AC%B8%EC%9D%84-%EC%BA%A1%EC%8A%90%ED%99%94-%ED%95%98%EC%84%B8%EC%9A%94

 

qkraudghgh/clean-code-javascript-ko

:bathtub: Clean Code concepts adapted for JavaScript - 한글 번역판 :kr: - qkraudghgh/clean-code-javascript-ko

github.com

 

70. 우선 onCountDownEnded 라는 네이밍으로 외부의 관심사를 이 안으로 끌고 들어오지 않은것은 매우 잘하신 부분이다.

const CountDown = ({ initialTimeBySecond, onCountDownEnded, children }) => {

...

// 끝났을 때
onCountDownEnded()

...
}

 

71.

  1. input 컴포넌트를 분리했다면 이 state는 input만 알고 있으면 되는 state 아닐까요?
  2. onChange, reset 에 따라서 이 state를 명령형으로 true/false toggle하는 것이 아닌 input에서 다루고 있는 value 값에 따라 disabled 를 제어하도록 (선언적으로) 코드를 작성해보면 어떨까요?
  3. 이렇게 하면 무엇이 좋을까요?

-> https://toss.im/slash-21/sessions/3-3

 

실무에서 바로 쓰는 Frontend Clean Code

실무에서 클린 코드의 의의는 유지보수 시간의 단축입니다. 동료 혹은 과거의 스스로 짠 코드를 빠르게 이해할 수 있다면 유지보수할 때 드는 개발 시간이 짧아집니다. 실제 예시와 함께 1. 응집

toss.im

 

72. 다음 3가지 조건을 통해 어떤 데이터를 상태로 관리할지 판단할 수 있다. 해당 조건을 하나라도 만족하면 state가 아니다.

  • 부모로부터 props를 통해 전달
  • 시간이 지나도 변하지 않음
  • 컴포넌트 안의 다른 state나 props를 가지고 계산 가능

73. typescript에서는 union type으로 정의하거나 (with template literal type) enum으로 정의해서 쓰곤 한다.

  const classnames = cx('Title', { [`Title--${size}`]: size });
  Title.propTypes = {
    size: PropTypes.oneOf(['small', 'medium', 'large']),
  }

 

74. custom hooks로 만들어보자. https://github.com/woowacourse/react-lotto/commit/26ba38f95737d6930ea7b9d924bb0cd7363cba13

 const [isLoading, setIsLoading] = useState(initialState.isLoading);
 const removeLoader = () => {
    setIsLoading(false);
  };
export function useToggle(initialValue = false) {
  return useReducer(prev => !prev, initialValue);
}

다른 잘 만들어진 Hooks를 먼저 살펴봐도 좋을 것 같네요! 검색해보면 많이 나와요! react-use 요런거라던가 react-spectrum 같은 오픈소스를 살펴보세요!

 

75. 👍

<html lang="ko">

 

76. Magic Number

 

77. 리액트스럽지 않은 부분

https://github.com/woowacourse/react-lotto/pull/69/files/100a4722df094bba8b47056f66d1cde3a440bc28#diff-f42582f6115ed2b9f601ece2b83a39b589123863ac4ab0a58905fc84ebe7fcf7

 

78. disabled와 더불어 cursor: not-allowed도 고려해보자.

https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

 

cursor - CSS: Cascading Style Sheets | MDN

The cursor CSS property sets the type of mouse cursor, if any, to show when the mouse pointer is over an element.

developer.mozilla.org

 

79.

  • Modal의 경우 Dimmed 배경을 제공했지만 그에 맞는 UI/UX는 부족해보인다. 예) ESC 키 대응 및 컴포넌트 외부 클릭시 대응 
728x90

'Tech > React' 카테고리의 다른 글

useEffect 정리  (0) 2021.07.22
[Typescript] CRA에서 http-proxy-middleware 사용법  (0) 2021.07.14
ReactNode vs ReactElement vs JSX.Element  (0) 2021.07.07
React component  (0) 2021.05.29
선언형 프로그래밍과 명령형 프로그래밍  (0) 2021.05.11

댓글