리액트 문서에서는 context를 소개하는 페이지에서 context를 쓰기 전에 component composition에 대해 고려해보라고 권장하고 있다. context는 여러 레벨의 여러 컴포넌트에서 같은 값을 공유하도록 해주므로 props drilling을 피할 수 있고, 불필요한 리렌더링을 피할 수 있다는 장점이 있다. 다만 context에도 단점이 존재하는데, implicit하다. props를 직접 넘겨주는 방법은 코드 상에서 해당 컴포넌트의 input이 무엇인지 확인할 수 있지만 useContext로 컴포넌트 내부에서 값에 접근하게 되면 해당 컴포넌트의 사용처에서는 컴포넌트 내부에서 어떤 값이 쓰이고 있는지 보이지 않는다. 그러므로 그 컴포넌트가 context provider 내부에서 쓰일 것이..
Reconciliation이란 코드에 diff가 생겼을 때 DOM에 반영하는 로직이다. 공식 독스에서 크게 2가지를 중심으로 설명한다. 하나는 루트 엘리먼트의 타입이고, 하나는 key 어트리뷰트다. Type diff of root element 루트 엘리먼트의 type이 다른 경우 DOM element인지 React element인지를 불문하고 트리를 tear down하고 rebuild한다. (e.g. 와 , 와 ) DOM이라면 해당 element를 제거하고 새로 삽입하고, React component라면 unmount했다가 새로 만들어서 mount한다.위 같은 경우 자식 컴포넌트는 동일하지만 root element의 type이 div와 span으로 다르므로, Counter 컴포넌트는 언마운트하고 새로 ..
회사에서 redux, rxjs, redux-observable을 사용하고 있는데 처음엔 왜 이런 복잡한 걸 쓰나 싶었지만 쓰다보니 또 편리한 점도 있고 해서, 한 번 정리하고 넘어가려고 쓰는 포스팅. 리덕스란 리덕스는 예측 가능한 상태 컨테이너다. (라고 공식 도큐먼트에 써있다) 여기서 예측 가능하다는 것이 중요하다. 상태가 앱의 여기저기에서 변화하고, side effect가 발생하다보면 상태가 어떻게 될지 예측하기 힘들어진다. 리덕스는 action과 reducer를 통해서 일정한 단방향으로 변화를 전달함으로써 상태 흐름을 예측할 수 있게 해준다. action이란 일어난 일 또는 일어나야만 하는 일(액션)을 묘사한 것이다. 예를 들어 TODO앱을 만들 때 가장 기본적인 기능이 TODO를 추가하는 것이므로..
렌더링이란 제너럴한 의미에서 렌더링이란 이미지를 나타내는 과정을 의미하고, 리액트에서의 렌더링이란 클래스 컴포넌트의 경우 render 함수의 실행을 말하고 함수형 컴포넌트의 경우는 함수 전체의 실행을 의미한다. (이하 render 함수를 실행한다고 표현하겠다) 참고로 함수형 컴포넌트는 진짜 함수라서 이렇게 쓰지 않고 {Component()} 라고 호출하는 것도 가능하다. 하지만 이렇게 하지 않기를 권장하고 있다. (Don't call function components. Render them.) 다시 말하자면 리액트의 렌더링 = render 함수 실행(혹은 함수형 컴포넌트 실행)이고, render 함수 실행의 결과로 react element tree가 산출된다. React element tree는..
React hook 중에 useImperativeHandle 이라는 훅이 있다. 이 훅은 forwardRef 를 사용해서 ref를 사용하는 부모 측에서 커스터마이징된 메서드를 사용할 수 있게 해준다. 예를 들어 아래처럼 정의하면, function ParentComponent() { // inputRef라는 동아줄을 만들어서 자식에게 보낸다 const inputRef = useRef(); return ( inputRef.current.realllyFocus()}>포커스 ) } function FancyInput(props, ref) { // 부모가 내려준 동아줄 ref에다가 이것 저것 작업을 한다 // 부모는 이 로직에 대해 모르고, 위로 끌어올리지 않고도 그냥 ref.current로 접근하여 사용만 하면..
리액트에서는 컴포넌트가 언마운트된 상태에서 setState() 가 호출되면 워닝을 표시한다. 언마운트된 컴포넌트에 setState()를 호출하는 것은 클린 업이 제대로 안돼서 컴포넌트가 언마운트된 다음에도 앱이 그 컴포넌트에 대한 참조를 가지고 있다는 뜻이고, 이는 메모리 누수를 일으킬 가능성이 있기 때문이다. 그래서 예전에는 지금은 deprecated된 isMounted() 로 마운트됐는지 조건을 체크한 다음 setState()를 호출하게 했는데, 이게 바람직하지 않은 이유는 워닝을 받아야 할 때에도 워닝을 받지 못할 경우가 생기기 때문이다. 그래서 _isMounted라는 프로퍼티를 만들어서 componentDidMount 에서 _isMounted를 true로 설정하고 componentWillUnmou..
문제 상황 material-ui의 drawer 컴포넌트를 사용하고 있음 부모 컴포넌트(검색 결과를 리스트로 보여주는 페이지)가 자식 컴포넌트인 drawer에게 state(인원 수)를 넘겨줌. drawer는 부모 컴포넌트로부터 받은 인원 수로 state를 초기화하고, drawer내에서 인원 수를 변동시킬 수 있음. drawer 내에서 인원 수를 변동시킨 다음 저장 버튼을 누르면 drawer가 닫히면서 바뀐 인원 수로 검색 api 재호출하여 그 결과를 부모 컴포넌트인 리스트 페이지에 렌더링함. 그런데 문제는 api call이 백그라운드에서 진행되고 있을 때, drawer를 열어서 인원 수를 조작하고 있는 상황에서, api 호출이 끝나고 리스트가 렌더링되면, drawer에서 조작하고 있던 인원 수가 다시 초기..
부모 컴포넌트에서 count라는 state를 갖고 있고 이를 prop를 내려줄 때, 자식 컴포넌트에서 이를 받아 state의 초기값으로 삼았다고 하자. 이후, 부모 컴포넌트에서 갖고 있는 count 값이 변동된다면 자식 컴포넌트가 표시하고 있는 state는 어떻게 될까? 변하지 않는다. 그 이유는 컴포넌트 생성자(constructer)는 컴포넌트가 마운트될 때 한 번만 실행되기 때문이다. constructer는 this.state의 초기값 적용, 인스턴스에 이벤트 처리 메서드를 바인딩 하기 위해 사용한다. class ChildComponent extends Component { constructer() { super(props); this.state = { count: this.props.value };..
switchMap 파라미터: 소스 옵저버블의 각 아이템에 적용될 함수. (e.g. of(1,2,3) 이면 1과 2와 3에 각각 적용될 함수) 이 함수는 옵저버블을 리턴한다. 즉 2차원으로 중첩된 옵저버블이 원래라면 생기게 된다. 이걸 간단히 배열로 생각하자면 [1,2,3].map($0 => [$0 * 2]) 이런 식으로 생각할 수 있다. 즉 map의 소스가 되는 아이도 배열이고, map 메서드의 파라미터로 주어지는 함수도 배열을 리턴하면, 결과는 2차원 배열이 되는 것처럼 생각하면 된다. (배열을 옵저버블로 치환해서 생각하면 됨) rx에서 모든 연산자는 옵저버블 인스턴스를 리턴하도록 되어있기 때문에, 옵저버블에 연산자를 매핑하면 원래라면 중첩된 옵저버블이 생기게 되는 것이다. 하지만 중첩된 옵저버블은 r..
React-Native Tutorial ClickThePaintings Code ClickThePaintingsWithRedux Code 컨트리뷰톤을 통해 RN팀에 참여하였고, RN iOS 예제 앱을 만들어 보게 되었다. RN은 처음이고, 짧은 시간 내에 예제 앱을 구현한 것이기에 기능은 매우 간단하다. 그림 데이터를 가져와서 클릭하면 그림의 세부 정보를 보여주는 것 리액트만 적용한 앱(ClickThePaintings)과 리액트, 리덕스, 리덕스 썽크를 적용한 앱(ClickThePaintingsWithRedux)을 별도로 구현했다. 기본적인 레이아웃은 두 앱 모두 동일하며, 리덕스를 적용한 앱에서는 API를 사용했기에 데이터를 fetch하는 동안 로딩 컴포넌트가 보여지도록 한 것만 다르다. 어쨌든 간단하..
Expo에서 React-Native CLI로 바꾸기 실패 앞서 리액트 네이티브 시작하기에서는 expo cli로 빌드했었는데, 팀에서 react-native-cli를 사용하자고 해서 다시 프로젝트를 eject해보았다. expo가 필요하지 않은 상황은 다음과 같다. 설치를 커스터마이즈하고 싶을 때 커스텀 모듈을 설치하고 싶을 때 커스텀 리액트 네이티브 모듈을 사용할 때 커뮤니티에 의해 디벨롭된 모듈과의 일관성을 원할 때 ReactJS의 새로운 피처를 사용하고 싶을 때 커스텀 CI/CD 가 필요할 때 expo 없이 rn앱을 빌드하려면 처음부터 react-native-cli를 사용해서 빌드하거나 expo 프로젝트를 eject하면 된다. Successfully copied template native code. ..
RN 개발 환경 세팅 크게 두 가지 방법이 있다. expo-cli react-native-cli expo-cli (formerly create-react-native-app) 장점과 단점 비기너 친화적. 리액트 프로젝트를 해봤으면 알겠지만 CRA가 환경 셋팅을 얼마나 쉽게 해주는가… 그것의 RN버전인 셈인 듯하다. expo cli의 주요 특징 중 하나는 큐알코드를 생성해서 이를 통해 디바이스로 앱을 실행할 수 있게 해주는 것, 그리고 코드가 변경될 때마다 자동적으로 디바이스 앱에 반영된다는 것이다. 반면 단점은 순수 자바스크립트 앱에서만 작용한다는 것이다. 어느 순간 스위프트나 오브젝트C, 자바, 코틀린 등을 사용해야 할 때가 오면 이 것을 걷어내야 한다. expo cli는 eject 커맨드를 제공하고 ..
useCallback 다음의 경우 버튼이 클릭될 때마다, Clicked와 Button rendered가 둘다 출력된다. App이 리렌더링될 때마다 Button도 리렌더링된다. class App extends Component { handleClick() { console.log("Clicked") } render() { return ( this.handleClick} /> ) } } class Button extends Component { render() { console.log('Button rendered'); return 버튼 } } 그러나 constructor 을 만들어 bind하면 버튼은 최초에 렌더된 후 버튼이 클릭될 때마다 Clicked만 출력된다. handleClick이라는 함수가 한 번..
react-redux connect를 Custom HOC로 만들기 react-redux의 connect함수는 리덕스 스토어와 리액트 컴포넌트를 연결해준다. 그래서 각 리액트 컴포넌트에서 바로 스토어로 쉽게 접근할 수 있다. 다만 connect함수를 통해서 접근하고 싶은 state나 action creator가 있는 경우 mapStateToProps나 mapDispatchToProps 로 연결해야 한다. 그리고 보통은 각 함수 내에서 연결하고 싶은 state 프로퍼티나 action creator를 특정한다. 그러다보면 connect가 쓰이는 컴포넌트마다 mapStateToProps, mapDispatchToProps 가 반복적으로 쓰이면서 코드가 중복될 수 있다. 일반적으로 connect함수가 쓰이는 모습..
Custom Hook 만들기 - 1 date-fns를 이용한 시간 표시 기능을 컴포넌트로 추출 후 이를 처리하는 커스텀 훅 만들기 Datetime Component 시간표시(eg. 몇분 전) 기능을 컴포넌트로 따로 추출 import distanceInWords from 'date-fns/distance_in_words_to_now'; import useUpdate from '@/hooks/useUpdate' // date-fns 함수 호출을 distance라는 함수 내에 넣기. 그래야 distance 함수가 불렸을 때 비로소 실행되도록 할 수 있다. const distance = (time) => { distanceInwords(time, { locale, addSuffix:true }); } // cr..
- Total
- Today
- Yesterday
- c언어
- Prefix Sums
- 리덕스
- 제네릭스
- Data Structure
- rxjs
- Session
- this
- GIT
- 인스턴스
- react
- JavaScript
- 개발 공부
- linkedlist
- CSS
- oracle
- package.json
- 깃
- youtube data api
- Java
- useEffect
- jQuery
- til
- 알고리즘
- getter
- Redux
- SQL
- Conflict
- 자바
- 포인터 변수
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |