ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React
    Node.js/프론트엔드 2021. 12. 3. 10:53

    1. UI를 빌드하기 위한 오픈 소스 라이브러리다.

    2. 프레임워크가 아닌 라이브러리다.

    3. UI에 집중한다 (HTTP request 핸들링, 라우팅은 다른 라이브러리들이 해줌.)

     

    컴포넌트 기반 아키텍처

    어플리케이션을 small encapsulated parts로 쪼갠 다음 복잡한 UI로 composed 된다. → 재사용 가능한 코드

     

    선언적

    React에 UI가 어떻게 생겼는지 알려주면 React가 그것을 실제 UI로 빌드해준다. 

     

    DOM 업데이트

    가장 비용이 많이 드는 연산 중 하나인데 React에서 그것을 멋지게 핸들링해준다.

     

    npx : npm package runner

    npx가 있으면 패키지를 전역 설치 안 하고 바로 사용할 수 있다

    예) npx create-react-app <project_name>

     

    JSX(JavaScript XML)

    1. JS 문법을 확장

    2. element와 컴포넌트를 위해 XML 같이 작성

    3. tag name, attribute, children 포함

    4. 리액트 어플리케이션에서 꼭 사용할 필요 없음.

    5. react 코드를 간단하게 만들어줌.

    6. 최종적으로 브라우저가 이해할 수 있는 pure js로 트랜스파일 해줌.

     

    JSX differences

    1. class → className

    2. for → htmlFor

    3. camelCase 프로퍼티 네이밍 컨벤션

     

    컴포넌트 props -> immutable하다(값 변경 불가)

    클래스 컴포넌트는 props를 this.props로 가져올 수 있다.

    https://stackoverflow.com/questions/47561848/property-value-does-not-exist-on-type-readonly

     

    Property 'value' does not exist on type 'Readonly<{}>'

    I need to create a form that will display something based on the return value of an API. I'm working with the following code: class App extends React.Component { constructor(props) { super(p...

    stackoverflow.com

    state를 set 함수를 사용하지 않고 직접 변경(this.state.count = this.state.count + 1처럼)하면 컴포넌트 리렌더링이 일어나지 않아 화면에 변경된 값이 표시되지 않는다.

    또 set 함수는 asynchronous하기 때문에 state를 console.log로 찍어보면 브라우저에 렌더링된 결과값과 콘솔에 표시된 결과값이 다르게 표시될 수 있다. 

    React group multiple set state calls into a single update for better performance.

    set 함수가 실행되면 컴포넌트가 리렌더링 되고, state 값이 변경된다.

     

    regular function => this 키워드는 함수를 호출한 object를 가리킨다. React 클래스 컴포넌트의 경우, 클래스 컴포넌트 내부에 regular function이 있다면, 해당 함수 내부의 this는 window 객체 또는 global 객체, document, button 등 어떤 것이든 가리킨다. 

    arrow function => this 키워드는 항상 arrow function이 선언된 오브젝트를 가리킨다.

     

    key prop : key는 list에 있는 item들이 변경됐는지, 추가됐는지, 제거됐는지 구분할 수 있게 해준다. UI를 핸들링하는 데 매우 중요한 역할을 한다.

    map 함수의 index parameter를 key로 사용하면 심각한 UI 이슈가 발생할 수 있다. =>

    index를 키로 사용할 수 있는 경우

    1. 리스트에 있는 아이템들이 unique id를 가지고 있지 않다.

    2. 리스트가 아이템들이 변하지 않는 static list다.

    3. 리스트 아이템들은 필터링되거나 재배치 되지 않는다.

     

    css 모듈 사용하는 방법

    - 파일명.module.css 로 파일 이름 작성

    - css 적용하고자하는 파일에서 import styles from './파일명.module.css로 import.

     

    컴포넌트 생명주기

    Mounting : 컴포넌트의 인스턴스가 생성되고 DOM에 insert 됨.

    constructor, static getDerivedStateFromProps, render, componentDidMount

    1. constructor(props)

    - 새로운 컴포넌트가 생성될 때마다 호출된다.

    - state를 초기화하거나 event handler들을 클래스 인스턴스에 바인딩할 때 사용.

    - side effect를 발생시키지 않으므로 HTTP request를 constructor 안에서 하면 안 된다.

    - super(props) 함수를 호출한다. 이는 base class constructor를 호출한다. super 함수에 props를 전달한 뒤에 this.props 사용 가능. 

    - constructor 안에서만 this.state를 바로 overwrite 할 수 있다. constructor 밖에서는 this.setState를 호출하여 state를 변경해야 한다.

    2. static getDerivedStateFromProps(props, state)

    - 컴포넌트의 state가 시간이 지남에 따라 props의 change에 의존할 때 사용.

    - state를 set한다. state object를 리턴.

    - side effect를 발생시키지 않으므로 HTTP request를 constructor 안에서 하면 안된다.

    3. render 메서드

    - required 메서드

    - props와 state를 읽어서 JSX를 리턴

    - render 메서드 안에서 state를 변경하거나 DOM과 상호작용하거나 ajax 호출을 하면 안된다.

    - children 컴포넌트들의 생명주기 메서드들 또한 실행된다.

    4. componentDidMount

    - 컴포넌트와 해당 컴포넌트의 모든 children 컴포넌트들이 DOM에 렌더링 되고서야 즉시 호출된다.

    - DOM과 상호작용하거나 ajax 호출로 데이터를 로드하는 등 사이드 이펙트를 발생시킨다.

     

    Updating : 컴포넌트의 props 또는 state에 변화가 생겨 컴포넌트가 리렌더됨.
    1. static getDerivedStateFromProps(props, state)

    - null 또는 update된 state를 뜻하는 object를 리턴

    - 컴포넌트가 리렌더 될 때마다 메서드 호출됨.

    - 사이드 이펙트 X

    2. shouldComponentUpdate(nextProps, nextState)

    - 컴포넌트를 리렌더해야하는지 안 해야하는지 결정. 기본적으로 컴포넌트는 props와 state가 변경되면 리렌더되는데 shouldComponentUpdate 메서드 내에서 false를 리턴하면 이런 동작을 막을 수 있다. 메서드 동작 방식은 기존의 props, state와 전달받은 props, state를 비교해서 리액트가 컴포넌트를 업데이트 해야할지 말지를 true, false를 리턴해서 알려준다.

    - 성능 최적화를 위한 메서드.

    3. render

    4. getSnapshotBeforeUpdate(prevProps, prevState)

    - virtual DOM의 변경사항이 DOM에 반영되기 전에 호출된다.

    - DOM으로부터 어떤 정보를 캡처하기 위해 사용.

    - 사용자의 스크롤 위치를 읽어서 업데이트 이후에 해당 스크롤 위치를 유지하는 등.

    - 메서드는 null 또는 value를 리턴하는데, 리턴된 value는 componentDidUpdate의 세번째 패러미터로 전달된다.

    5. componentDidUpdate(prevProps, prevState, snapshot)

    - 리렌더 사이클에서 render 이후 호출된다.

    - 사이드 이펙트 발생. ajax call 하기 전에 이전 props와 새로운 props에 변화가 있는지 확인 후 결정.

     

    Unmounting : DOM에서 컴포넌트가 제거됨. 

    componentWillUnmount

    - 컴포넌트가 언마운트되어 삭제될 때 호출됨.

    - 네트워크 요청을 취소하거나, 이벤트 핸들러 제거, subscription 취소, 타이머 invalidating 등을 함.

    - setState 메서드 호출하면 안 됨.

     

    Error Handling : 렌더링되는 동안 lifecycle 메서드 또는 child 컴포넌트의 생성자에서 에러 발생. 

    Error Boundary

    - 생명주기 메서드인 getDerivedStateFromError 또는 componentDidCatch를 구현하는 클래스 컴포넌트는 error boundary가 된다.

    - Error Boundary는 child 컴포넌트 트리에서 JavaScript 에러를 잡아내고, 에러를 기록하고, fall-back UI를 보여주는 리액트 컴포넌트다.

    - getDerivedStateFromError와 componentDidCatch를 클래스 컴포넌트 내에서 정의하면 해당 컴포넌트는 에러 바운더리가 된다.  

    - 에러 바운더리 배치에 따라 전체 앱이 fall-back UI를 가질지 아니면 문제가 발생한 컴포넌트만 가질지를 제어할 수 있다.

     

    1. static getDerivedStateFromError

    getDerivedStateFromError는 에러가 발생한 후에 fallback UI를 렌더하기 위해 사용된다.

    2. componentDidCatch

    componentDidCatch는 에러 로그를 기록하기 위해 사용된다. 

     

    Pure Component

    Shallow Comparison을 통해서 이전 state와 props, 다음 state와 props 값을 비교한다. shouldComponentUpdate를 사용하지 않아도 되고, 불필요한 렌더링을 줄일 수 있다.

     

    Portal

    부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 방법 제공. 

    => react-dom 의 ReactDOM.createPortal 사용

     

    HOC(Higher Order Components)

    - 함수가 컴포넌트를 argument로 받고 새로운 컴포넌트를 리턴하는 패턴.

    - const NewComponent = higherOrderComponent(originalComponent)

    - hoc는 additional data나 functionality를 original 컴포넌트에 추가한다.

    - const EnhancedComponent = higherOrderComponent(originalComponent)

     

     

    Warning: Can't perform a React state update on an unmounted component. => memory leak 발생. 해결하려면 useEffect의 cleanup function을 통해  모든 subscription과 비동기 작업을 취소.

    // class 컴포넌트의 경우
    componentDidMount() {
    	window.addEventListener('mousemove', this.logMousePosition)
    }
    
    componentWillUnmount() {
    	window.removeEventListener('mousemove', this.logMousePosition)
    }
    
    // functional 컴포넌트의 경우
    useEffect(() => {
    	window.addEventListener('mousemove', logMousePosition)
        
        return () => {
        	window.removeEventListener('mousemove', logMousePosition)
        }
    }, [])

    useEffect(() => {}) 모든 렌더마다 콜백 함수 실행.

    dependency array : useEffect가 주시해야할 모든 변화

     

     

    useReducer 

    - 상태 관리를 위해 사용되는 hook

    - useState의 대체재

    - useState는 useReducer로 만들어짐. 

    - useReducer vs useState?

     

    useState - state

    useEffect - side effects

    useContext - context API

    useReducer - reducers

     

    useCallback은 function instance 자체를 캐싱하고, useMemo는 function 호출의 결과를 캐싱한다.

    즉 function을 캐싱해야하면 useCallback을 사용하고, function의 결과값을 캐싱해야하면 useMemo를 사용한다.

     

    Warning: [antd: Form.Item] `defaultValue` will not work on controlled Field. You should use `initialValues` of Form instead.

    https://stackoverflow.com/questions/61244343/defaultvalue-of-input-not-working-correctly-on-ant-design

    'Node.js > 프론트엔드' 카테고리의 다른 글

    NextJS  (0) 2021.11.25
    Redux의 원리와 불변성  (0) 2021.05.14
    가로 스크롤 만들기  (0) 2021.04.01
    [ESLint] eslint.workingDirectories 옵션  (0) 2020.12.27
    프론트엔드 개발 환경의 이해 - NPM  (0) 2020.12.01
Designed by Tistory.