ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • "리액트를 다루는 기술" 책을 읽고 내용 정리중
    읽은 책/리액트 2018. 9. 10. 21:11

    "리액트를 다루는 기술" 책을 읽고 정리 ( 저자 : 김민준 )

    저자 블로그 : https://velopert.com/reactjs-tutorials

    저자 블로그 :  https://velog.io/@velopert/tags/react

    [1장] 리액트시작


    [ 리액트 ]

    * 페이스북에서 고안.

    * 어떤 데이터가 변할 때마다 어떤 변화를 줄지 고민X 

    * 기존 뷰를 날려버리고 새로 렌더링

    * BUT, 이 방식대로 하면 CPU 점유율도 많이 잡아먹고 메모리도 많이 사용할텐데.. > 하지만 잘 구현한 것이 React!

    * 오직 View 만 신경쓰는 라이브러리 ( 프레임워크가 아니다! )

    * 리액트의 초기 렌더링과 리렌더링

    * 이것으로 성능을 아끼고 최적의 유저 경험을 제공한다.


    [초기 랜더링]

    * render() {...} 

    * 어떻게 보일지를 정하는 초기 렌더링 함수

    * 컴포넌트가 어떻게 생겼는지 정의하는 역할

    * 뷰가 어떻게 생겼고 어떻게 작동하는지 정보를 지닌 객체를 반환.

    * 컴포넌트 안에 컴포넌트 들어 갈 수 있다.


    [ 조화 과정]

    * 뷰를 업데이트 하는 방법  > 조화 과정(reconciliation)을 거친다 라고 표현

    * 뷰가 변형되는 것처럼 보이지만, 사실은 새로운 요소로 갈아 끼우는 작업.

    * render 함수로 reconciliation.

    * 컴포넌트는 데이터를 업데이트했을 떄, 단순히 업데이트한 값을 수정하는 것이 아니라 새로운 데이터를 가지고 render 함수를 다시 호출함.


    [ 리액트 특징]

    [Virtual DOM]

    * DOM : Document Object Model : 객체로 문서 구조를 표현하는 방법 : XML 이나 HTML 로 작성.

    * DOM 은 동적 UI 최적화 되어 있지 않다. 정적이다.

    * DOM이 많아지고 변화가 일어나면 웹브라우저가 CSS를 다시 연산하고, 레이아웃을 구성하고, 페이지를 리페인트 하는데 시간이 허비된다. 

    ( DOM은 느리지 않다. )

    * 해결법 : COM 을 최소한으로 조작하여 작업을 처리하는 방식으로 개션 필요.

    * 따라서 리액트는 Virrual DOM 방식을 사용하여 DOM 업데이트를 추상화함으로써 DOM 처리횟수를 최소화하고 효율적으로 진행한다.


    * Virtual DOM 동작 방식

     데이터 업데이트 > 전체 UI virtual dom 에 리렌더링 > 이전 virtual dom 에 있던 내용과 비교 > 바뀐 부분만 실제 DOM에 적용



    [2장] JSX

    * jsx

    * JSX 는 자바스크립트의 확장 문법

    * JSX 는 나중에 코드가 번들링되면서 babel-loader를 사용하여 자바스크립트로 변환됨.


    * JSX 의 장점

    * 보기 쉽고 익숙하다.



    [3장] 컴포넌트

    [ props ]

    참고 리액트 reference : https://reactjs.org/docs/typechecking-with-proptypes.html

    * properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소.

    * props 는 부모 컴포넌트에서만 설정 가능

    * props 는 readOnly 


    * 부모에서 props 설정

    <MyList name="test">

    * 자식에서 props 접근 

    {this.props.name}

    * 자식에서 부모가 props 설정하지 않을때 기본값 설정 방법

    static defualtProps = {

    name : "기본값"

    }

    * props 의 type이 어떤건지 설정

      static propTypes = {

        name: PropTypes.string,

        age: PropTypes.number.isRequired

      }



    [ state ]

    * state 초기값 설정

    * 방법 1

    * 생성자를 만들어서 그 메소드 안에서 state 설정

    super(props); 필수로 들어가야 한다.!

    class TestComponent extends Component {

      constructor(props) {

        super(props);  

        this.state = {

            number:0

        }

      }

    }

    * 방법 2

    state = {

        number : 0

      }

    * 사용 

    * {this.state.number} 

    * state 값 업데이트

    * this.setState({ 필드:값, 필드:값 });


    [4] 이벤트 핸들링

    참고 리액트 reference 

    * 주의사항

    1. 이벤트는 카멜표기법 사용

    onClick, onKeyUp

    2. 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달한다.

    * 함수 bind 방법 1

      handleChange(e) {

        this.setState({

          message : e.target.value

        });

      }

      handleClick(e) {

        alert(this.state.message);

        this.setState({

          message:''

        });

      }


    render() {

    ...

    <input

              type = "text"

              name = "message"

              value = {this.state.message}

              placeholder = "아무거나 입력해보세요"

              onChange = {this.handleChange.bind(this)}

            />

            <button onClick={this.handleClick.bind(this)}> 메세지노출

            </button>

    ...

    }

    * 함수 bind 방법 2 ( 바벨의 transform-class-properties 사용 )

    * render에 있던 bind가 사라짐.

      handleChange = (e) => {

        this.setState({

          message : e.target.value

        });

      }

      handleClick = (e) => {

        alert(this.state.message);

        this.setState({

          message:''

        });

      }


    render() {

    ...

    <input

              type = "text"

              name = "message"

              value = {this.state.message}

              placeholder = "아무거나 입력해보세요"

              onChange = {this.handleChange}

            />

            <button onClick={this.handleClick}> 메세지노출

            </button>

    ...

    }

    3. DOM 요소에만 이벤트를 설정할 수 있다.


    [5] ref:DOM에 이름 달기

    참고 리액트 reference : https://reactjs.org/docs/refs-and-the-dom.html

    * ref 

    * DOM에 id를 주는 것처럼 리액트 프로젝트 내부에서 이름을 주는 방법

    * DOM을 꼭 직접적으로 건들여야 할때 사용 ( 대부분은 state로 처리 가능 )

    * 특정 input에 포커스 주기

    * 스크롤박스 조작하기

    * Canvas 요소에 그림그리기 

    * 사용법

    * ref 할당

    <input ref={ (ref)=> {this.inputPassword=ref} }/>

    * 불러오기

              this.inputPassword.focus();


    [6] Map

    * 배열 랜더링

    * 배열로 랜더링 시에는 key를 꼭 할당해줘야한다.

    * 어떤 값에 변화가 있었는지 알기 위해서


    [7] 라이프 사이클

    https://jaeyeophan.github.io/2018/01/01/React-4-Component-Life-Cycle/

    * 대부분의 컴포넌트는 componentWillMount를 사용하지 않아야 함 

    * 루트 컴포넌트에서 App과 관련된 외부 API를 설정할 때만 사용

    * componentDidMount

    * Ajax 호출을 시작하여 컴포넌트에서 사용해야 하는 데이터를 로드합니다.

    * setState를 호출할 수 있습니다.

    * componentWillReceiveProps

    * 초기 렌더링시 호출되지 않음 ( 비교할 Props 가 없으므로 ) 

    * 해당 컴포넌트의 상태 변경에 영향을 끼지는 props의 변경에 따라 로직을 구성합니다.

    * setState를 호출할 수 있습니다.

    * shouldComponentUpdate

    * 설정을 잘못하면 리랜더링이 안되므로 사용안하는게 낫지 않을까?

    * componentWillUpdate

    * shouldComponentUpdate를 사용하는 곳에서 리랜더링이 필요한곳에서 쓰므로 사용할 일 별로 없을듯



    [9] 리액트 컴포넌트 스타일링

    기존 내용 블로그 : https://velopert.com/3447

    신규 내용으로 업데이트 : https://velog.io/@velopert/react-component-styling#sass-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0


    [12] 리덕스 개념 이해

    기존 todoList에서는 App.js에서 다 관리했는데, Props로 관리 하다보면, 어려움이 많음.

    ( 불필요한 랜더링이 일어나므로 최적화도 해줘야 하며, 실제 컴포넌트는 필요하지 않지만, 자식 컴포넌트 때문에 필요해서 Props를 많이 들고 있을 수도 있다. )

    * 리덕스 용어

    * 스토어 : 애플리케이션의 상태 값들을 내장하고 있습니다.

    * 액션 : 상태 변화를 일으킬 떄 참조하는 객체입니다.

    * 디스패치 : 액션을 스토어에 전달하는 것을 의미합니다.

    * 리듀서 : 상태를 변화시키는 로직이 있는 함수입니다.

    * 구독 : 스토어 값이 필요한 컴포넌트는 스토어를 구독합니다.

    * 액션

    스토어에서 상태 변화를 일으킬 때 참조하는 객체

    반드시 type 값을 가지고 있어야함.

    타입은 해당 액션이 어떤 작업을 하는 액션인지 정의, 대문자와 밑줄을 조합하여 생성

    액션생성함수(action creator) : 액션을 만들어주는 함수 사용


    * 리듀서

    상태에 변화를 일으키는 함수

    현재상태 파라미터, 액션 객체 두 개의 파라미터를 받음

    함수 내부에서는 switch 문을 사용하여 action.type에 따라 새로운 상태를 만들어서 반환.

    initialState 값 설정 필요.

    리듀서 함수를 직접 실행하는 일은 없음

    * 리덕스 스토어

    스토어 생성시 createStore 함수 사용

    첫 번째 파라미터 : 리듀서 함수 , 두 번째 파라미터 : 해당 값을 스토어의 기본 값으로 사용.( 없으면 초깃값을 스토어의 기본값으로 사용 )

    * 구독

    ...

    * dispatch

    store.dispatch 함수 사용.


    - 리덕스의 3가지 규칙!!

    * 스토어는 단 한 개!

    단 리듀서를 여러개 만들어서 관리 가능

    * state는 읽기 전용.

    state 값을 직접 수정하면 안됨!

    새 상태 객체를 만들어서 넣어줘야함!!

    * 변화는 순수 함수로 구성

    모든 변화는 순수 함수로 구성해야함. 함수란 리듀서 함수!

    결과 값을 출력할 때는 파라미터 값에만 의존해야한다. 같은 파라미터는 언제나 같은 값을 출력해야 한다.

    ( 외부 API, DB 접근 NO!, DATE나 random 함수도 사용 NO!)

    * html에서 <body> 사이에 넣어준다.

     <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>

    * 자바스크립트 소스


    [13] 리덕스로 리액트 애플리케이션 상태 관리

    * 상태 관리 라이브러리를 따로 사용하지 않고, state만 사용시 문제점

    * 상태 객체가 너무 복잡하고 큽니다.

    * 최상위 컴포넌트에서 상태관리를 하는 메서드를 너무 많이 만들어 코드가 복잡합니다.

    * 하위 컴포넌트에 props를 전달하려면 여러 컴포넌트를 거쳐야 합니다.


    * 아래 2개 컴포넌트로 나눌 때 이점.

    * 유저 인터페이스와 상태를 다루는 데이터가 분리되어 프로젝트를 이해하기 쉽다.

    * 컴포넌트 재사용율도 높다.

    * 프리젠테이셔널 컴포넌트

    * 오직 뷰만 담당

    * 프리젠테이셔널 컴포넌트와 컨테이너 컴포넌트 있을 수 있음. 

    * props 로만 데이터 가져옴. ( 리덕스 스토어에 직접 접근 권한 하지 않음 )

    * state 없음 ( UI 와 관련된거면 OK )

    * 컨테이너컴포넌트

    * 프리젠테이셔널 컴포넌트들과 컨테이너 컴포넌트들의 관리를 담당.

    * DOM 엘리먼트 가지고 있지 않음.

    * 상태를 가지고 있을 때가 많고, 리덕스에 직접접근 가능


    * Provider 

    react-redux 라이러브러리에 내장된 리액트 애플리케이션에 손쉽게 스토어를 연동할 수 있도록 도와주는 컴포넌트

    이 컴포넌트를 불러온 후 연동할 프로젝트의 최상위 컴포넌트(이 프로젝트에서는 App 컴포넌트)를 감싸고, Provider 컴포넌트의 props로 store를 넣어주면 됩니다.


    * react-redux 라이브러리의 connect 함수

    3개의 파라미터있음. 불필요하다면 생략가능

    connect([mapStateToProps], [mapDispatchToProps], [mergeProps])

    mapStateToProps : store.getState() 결과 값인 state를 파라미터로 받아 컴포넌트의 props로 사용할 객체를 반환

    mapDispatchToProps : dispatch를 파라미터로 받아 액션을 디스패치하는 함수들을 객체 안에 넣어서 반환

    mergeProps : state와 dispatch가 동시에 필요한 함수를 props로 전달해야 할 때 사용하는데, 일반적으로는 잘 사용하지 않습니다.


    * 프로젝트에서 개발자도구 사용할수 있게하는 설정..
    const store = createStore(reducers, window.devToolsExtension && window.devToolsExtension());



    https://velopert.com/3358

    '읽은 책 > 리액트' 카테고리의 다른 글

    React 초보의 알아둘 내용  (0) 2018.09.15
Designed by Tistory.