JIGGAG

6월 한달동안 로그

2022년 7월 3일

읽어보았던

  • 훅을 사용할 때 주의할 점
    • 함수형 컴포넌트에서는 상태를 저장하는 로직과 렌더링하는 로직을 쉽게 분리
      • 잊지말고 🚨
    • 무언가 새로운 것을 꿈꾸며 읽어내려갔는데 아차 싶었다
      • 기본적인 것을 되짚어 보는 것이 더 중요했다
    • 가장 중요한 부분은 훅의 디펜던시로 어떤게 들어가는지
    • 린트를 설정해두고 autofix? 하게 되면 가끔 의도치 않게 과하게 디펜던시가 설정되는 경우가 있다
    	const User({ user }) {
    	  useEffect(() => {
    	    console.log(user.name)
    	  }, [user]) // 디펜던시가 과하다
    	
    	  return <span>{user.name}</span>
    	}
    
    • 위 예제와 같은 경우, useEffect의 디펜던시가 autofix로 user 객체가 통째로 들어가버리는 상황이다
    • 직접적으로 디펜던시를 걸어준다면 user.name을 명시했을텐데, 친절한 린트가 과한 경우가 가끔있다
      • 아마 user.name, user.age 등 여러개를 사용하고 있는 경우 린트가 user를 통째로 넣어주는 것 같다
    • 하지만 이런 경우 처음에는 발견하지 못하다가 나중에 퍼포먼스 이슈에 가장 큰 원인이 되고 있는 것을 여러번 발견했다
    • 그렇기 때문에 프리미티브 타입을 사용하거나 오브젝트를 사용하더라도 직접 명시하는 것을 지향하고 있다
      • 하지만... 한땀한땀 추가해둔 디펜던시는 autofix 한번에 합쳐져버리는데 ctrl+Z 🙈

6/26 ~ 6/30

코뿔소

  • 10 주 동안 봤던 책을 드디어 닫았다
  • 이정도면 벌써 잊혀져가는 기간
  • 마음가짐이 중요한데 처음에는 재밋고 쉬우니깐 한번에 쭉쭉 나가던 것도 후반부 갈수록 미뤄진듯하다
  • 이런 반성을 하면서 바로 준비해둔 다음 스터디로 넘어가야지
  • 준비랑 시작이 제일 재밋는걸!

6/19 ~ 6/25

WKWebView 쿠키 관리

  • WKWebViewUIWebView
    • 쿠키를 삭제했는데 삭제되지 않는다
    • 앱을 완전히 종료 후 다시 시작해야지만 쿠키가 사라지는데
    • 왜?
  • 참고: WKWebView 쿠키 관리
  • UIWebViewWKWebView로 바꿔가면서 겪게 되는 이슈인 것 같다
  • 기존에 UIWebView에서는 쿠키를 일괄적으로 NSHTTPCookieStorage에서 관리하고 있었는데
  • WKWebView로 넘어오면서 WKWebsiteDataStore를 이용해 직접 각각의 웹뷰에서 관리하게 되었다
    • WKProcessPool를 이용해 A, B, C 웹뷰 간 쿠키 공유가 가능하긴 하다
  • 세상의 모든 쿠키를 한 바구니에 넣고 꺼내 쓰다가, 각각 접시에 담아두고 원하는 것을 꺼내써야하는 기분
  • 그럼 위에서 문제가 발생한 쿠키를 삭제했는데 삭제가 되지 않았다라는 것은 어떤 상황일까?
    • UIWebView > WKWebView 마이그레이션 과정에서 쿠키 관리를 놓쳤다
    • NSHTTPCookieStorage가 아니라 WKWebsiteDataStore로 관리해야함을

6/12 ~ 6/18

다시 반공변성

  • 왜 다시 여기로 돌아왔는지 모르겠지만
  • 다시 보고 싶어서 보는 중: 공변성이란 무엇인가
  • 이런저런 코드를 보다보면 메서드 타입 정의 방식이 혼합되어있는 경우가 있는데, 마음이 신경쓰인다 (하나만 사용하고 싶어서...)
  • 메서드 타입 정의 방식은 줄여쓰기와 프로퍼티 표현 방식이 있다
    interface Fn<T> {
    	// 줄여쓰기
    	shorthand(param: T): void;
    
    	// 프로퍼티
    	property: (param: T) => void;
    }
    
  • 이런 방법의 차이는 함수 파라미터의 공변/반공변성을 지원 여부에 차이가 있다
    • 줄여쓰게 되면 파라미터는 공변 + 반공변 = 이변성을 가지게 된다
    • 이렇게 되면 의도하지 않은 타입에러가 발생할 수 있다 (string만 들어올줄 알고 length를 썼는데, boolean이 들어와서 오류가 발생하는..)
  •   type Type<T> = (param: T) => void;
    
    let base: Type<string | string[]> = (param) => {
      	console.log(param.length); // string 타입에 대한 로직
      console.log(param.slice(0, 0)); // string[]에 대한 로직
    };
    
    const 공변: Type<string> = (param) => {
      	console.log(param.length);
    };
    const 반공변: Type<string | string[] | number[]> = (param) => {
      	console.log(param.length);
      console.log(param.slice(0, 0));
    };
    
    base = 공변; // 타입에러 발생
    base = 반공변; // 정상
    
    • 위에 base 함수에는 허용된 파라미터 타입 string과 string[]에 대한 로직이 포함되어있다
    • 이런 base 함수에 공변성을 갖고 있는 함수를 할당하게 된다면 타입에러가 발생한다
      • TS2322: Type 'Type<string>' is not assignable to type 'Type<string | string[]>'.   Type 'string | string[]' is not assignable to type 'string'.     Type 'string[]' is not assignable to type 'string'.
      • 공변성을 허용한다면 string[]에 대한 로직을 처리할 수 없게 된다
    • 반대로 반공변성을 할당하게 된다면 정상적으로 동작한다
      • base 함수에서 처리하고 있던 타입 string, string[]에 대한 로직을 정상적으로 처리할 수 있기 때문이다
  • 일반적으로 반공변성을 허용해야하고 공변성을 필요로하는 상황이 있을까? 하는 생각이다

6/5 ~ 6/11

효율적인 컴포넌트

  • Effective Component 지속 가능한 성장과 컴포넌트
    • 전에 Headless 관련해서 블로그를 봤었는데, 역시 직접 보는게 훨씬 이해가 쉬웠다
  • Headless 추상화
    • 한가지 역할을 하도록
    • 데이터와 UI를 분리
    • 캘린더에 필요한 데이터를 관리하는 것을 훅으로 빼고 UI를 담당하는 부분들이 이 훅에서 가져온 데이터를 사용해 그리는 것
    • UI랑 상호작용을 분리
    • 상호작용을 훅으로 빼고 이 훅에서 가져온 함수를 사용하도록 하는 것
    const { data, title } = useCustomData();
    const onPress = useCustomAction();
    
    ...
    
    return <CustomComponent data={data} title={title} onPress={onPress} />;
    
    • 이렇게 데이터, UI, 액션을 분리하여 구성한 CustomComponent는 유연하게 동작할 수 있게 된다
  • 컴포넌트에 종속되는 도메인을 걷어내고 일반화하면 어떨까
    • 누구나 알기 쉬운 이름을 지어준다던지
    • 인터페이스 표준화 => 재사용성, 독립성

6/1 ~ 6/4

RN

  • 빌드 오류가 발생해서 v0.69를 너무 빨리 시작한 것을 후회했는데
  • rc6으로 올리고 pod 새로 받으니 된당...
  • 🙈
  • iOS만 되는거고 ㅠㅠ 안드로이드는 ㅠㅠ
    • * What went wrong: Error resolving plugin [id: 'org.jetbrains.kotlin.android', version: '1.6.10']
    • > Plugin request for plugin already on the classpath must not include a version
    • 왜!
    • 범인은 ../node_modules/react-native/ReactAndroid/build.gradle
    • 말도 안해주고 코틀린 버전을 1.6.10을 쓰고 있었네
    • RN이 그렇다면 내가 따라야지
  • 근데?
    • 나는 코틀린 버전을 org.jetbrains.kotlin:kotlin-gradle-plugin에서 사용하려고 하는건데
    • org.jetbrains.kotlin.android 랑 충돌이 난다고?
    • 둘이 무슨 관계가 있는듯하여 org.jetbrains.kotlin:kotlin-gradle-plugin를 제거
    • 그랬더니 다른 오류 발생
    • Plugin [id: 'kotlin-android'] was not found in any of the following sources:
    • org.jetbrains.kotlin.android를 쓰기로 하면서 기존에 사용하던 플러그인 kotlin-android + kotlin-gradle-plugin 조합을 제거해주면 될 것 같다
    • 관련해서 좀 더 찾아보니 org.jetbrains.kotlin.android을 사용하는 방법의 차이인 것 같은데
    • ReactAndroid에서 DSL로 사용해버리면서 충돌이 발생했고 app에서 사용하던 방식도 DSL 기준으로 정리해주었다는 느낌이다
    • if (org.jetbrains.kotlin.android === kotlin-android)