리액트 교과서 chapter05
(React 컴포넌트의 라이프사이클 이벤트)

React는 라이브 사이클 이벤트를 기반으로 컴포넌트의 동작을 제어하고 사용자 정의 할 수 있다.

  • 마운팅 이벤트: React 엘리먼트를 DOM노드에 추가할 때 발생
  • 갱신이벤트: 속성이나 상태가 변경되어 React 엘리머트를 갱신할 때 발생
  • 언마운팅 이벤트 : React 엘리먼트가 DOM에서 제거될 때 발생

마운팅과 언마운팅의 경우 DOM의 추가, 삭제 과정에 동작하므로 1번만 동작하며, 갱신은 상태의 변경에 따라 동작하기 때문에 여러번 동작 될 수 있다.

  • contructor: 상태의 초기화 시 사용 된다.
  • 마운팅
    • componentWillMount(): DOM에 삽입 전에 실행된다.
    • componentDidMount(): DOM에 삽입 후에 실행된다.
  • 갱신
    • componentWillReceiveProps(nextProps): 컴포넌트가 속성을 받기 직전에 실행
    • shoudComponentUpdate(nextProps, nextState): 컴포넌트가 갱신되는 조건을 정의해서 재랜더링을 최적화 할 수 있다. boolean 값을 반환
    • componentWillUpdate(nextProps, nextState): 컴포넌트가 갱신되기 직전에 실행된다.
    • componentDidUpdate(prevProps, prevState): 컴포넌트가 갱신된 후에 실행된다.
  • 언마운팅
    • componentWillUnmount(): DOM에서 제거하기 전 실행되며, 구독한 이벤트를 제거하거나 다른 정리작업에 수행 할 수 있다.

 

라이프 사이클의 사용 및 관찰

class Clock extends React.Component {

  constructor(props) {
    super(props)
    this.launchClock()
    this.state = {
      currentTime : (new Date()).toLocaleString('kr'),
      testState : 'testState',
      counter : 0 
   }
  }

  launchClock() {
    setInterval(() => {
      this.setState({
        currentTime: (new Date()).toLocaleString('kr'),
        counter: ++this.state.counter
      })
    }, 1000)
  }

  render () {
    if (this.state.counter > 2) {
      return <Logger time={this.state.currentTime}></Logger>
    }
    }
}

class Logger extends React.Component {
  constructor (props) {
    super(props)
    console.log('constructor 실행')
  }
  componentWillUnmount() {
    console.log('componentWillUnmount 실행')
  }
  componentDidMount() {
    console.log('componentDidMount 실행')
  }
  componentWillReceiveProps(nextProps) {
    console.log('componentWillReceiveProps 실행')
    console.log('새로운 속성', nextProps)
  }
  shoudComponentUpdate(nextProps, nextState) {
    console.log('shoudComponentUpdate 실행')
    console.log('새로운 속성', nextProps)
    console.log('새로운 상태', nextState)

  }
  componentWillUpdate(nextProps, nextState){
    console.log('componentWillUpdate 실행')
    console.log('새로운 속성', nextProps)
    console.log('새로운 상태', nextState)
  }
  componentDidUpdate(prevProps, prevState){
    console.log('componentDidUpdate 실행')
    console.log('이전 속성', prevProps)
    console.log('이전 상태', prevState)
  }
  componentWillUnmount(){
    console.log('componentWillUnmount 실행')
  }
  render () {
    return <div>{this.props.time}</div>
  }
} 

 

componentDidMount의 활용

기본적인 템플릿이 mount 된 뒤 데이터 조회

  class UserList extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        userList : [{id: '1', username:'1'}]
      }
    }
      componentDidMount() {
        this.getUserList()
      }

      getUserList() {
        fetch('https://jsonplaceholder.typicode.com/users/')
        .then((response) => {return response.json()})
        .then((users) => {
          this.setState({userList : users})
        })
      }

      render() {
        return <div>
          <table>
            <tbody>
              {this.state.userList
              .map((user) => 
                <tr key={user.id} id={user.id}>
                  <td>{user.username}</td>
                  <td>{user.email}</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>

      }
  }

 


https://github.com/Kmmanki/react_note/tree/master/chapter05

 

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

 

 

리액트 교과서 chapter04(React 컴포넌트의 상태)

React 컴포넌트의 상태

현재까지는 props를 사용하여 뷰를 갱신하였다. 하지만 pros(속성)은 컴포넌트의 생성시에 전달 받는 값이기 때문에 변경을 감지하여 뷰를 갱신 할수 없다.

React 컴포넌트의 상태를 이용하여 이러한 문제를 해결 할수 있다. 상태(state)는 컴포넌트에 데이터를 저장하고 데이터의 변경에 따라 자동으로 뷰를 갱신하도록 하는 핵심 개념이다.

초기 상태(state) 설정

class Clock extends React.Component {
  constructor(props) {
    super(props)
    // 초기상태 세팅
    this.state = {currentTime : (new Date()).toLocaleString('') }
  }
  ...
}

 

상태(state)의 사용

...
render () {
    return <span >Current Time is : {this.state.currentTime}... </span>  
    }

 

상태(state)의 변경

setState를 사용하지 않은변경은 적용되지 않는 안티패턴이다.
setState에 포함된 데이터만 변경된다. 즉 testState는 변경되지 않는다.

class Clock extends React.Component {

  constructor(props) {
    super(props)
    this.launchClock()
    // 두 state를 초기화
    this.state = {
      currentTime : (new Date()).toLocaleString('kr'),
      testState : 'testState'
   }
  }

  launchClock() {
    // 1초마다 state의 currentTime를 갱신
    setInterval(() => {
      console.log('updating time...')
      this.setState({
        // currentTime state만 변경
        currentTime: (new Date()).toLocaleString('kr') 
      })
    }, 1000)
  }

  render () {
    return <div className="block">
      // setState를 통해 상태변경
      <span className="block">{this.state.testState}</span>
      <span className="block">Current Time is : {this.state.currentTime}... </span>  
    </div>
    }
}

 

상태 객체와 속성

상태 객체와 속성은 모두 클래스의 멤버이며 각각 this.state, this.props를 말한다.
차이점

  1. 상태 객체는 변경이 가능하지만 속성은 변경이 불가능하다.
  2. props는 부모 컴포넌트로 부터 전달하지만, 상태 객체는 해당 컴포넌트가 정의한다.

https://github.com/Kmmanki/react_note/tree/master/chapter04

 

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

 

 

 

 

React 교과서 chapter03(JSX)

JSX

챕터2 까지의 Element 생성은 React의 createElement 함수에 각각의 인자를 넣는 방식으로 개발을 하였다.
해당 Element가 적고 복잡하지 않다면 크게 문제가 없지만 복잡해질 수록 가독성이 떨어진다는 단점이 있다.
이를 보안하기 위한 것이 JSX이다.
JSX는 기존의 HTML태그를 사용하는것과 매우 유사하다.

 

JSX 방식

class HelloWorld extends React.Component {
  render() {
    return (
      <h1>hello world</h1>
    )
  }
}

const el =document.getElementById('content')
var root = ReactDOM.createRoot(el)

root.render(
  React.createElement(HelloWorld, null)
)

JSX의 설치

  1. npm init: pagkage.json 생성
  2. package.json에 babel 추가:
    "barbel": {
    "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
    ]
    },
  3. npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-react: 설치

 

JSX의 컴파일

.\node_modules.bin\babel .\jsx -o .\js\script-compield.js
jsx 디렉토리의 모든 파일을 js디렉토리의 script-compield.js로 변환


.\node_modules.bin\babel .\jsx -o .\js\script-compield.js -w
-w 옵션은 해당 파일의 변경을 감지하여 자동 빌드

index.html 소스 수정

<script src="./js//script-compield.js" type="text/javascript">

 

JSX의 변수의 출력

class DateTimeNow extends React.Component {
  render () {
    let dateTimeNow = new Date().toLocaleTimeString()
    return <span>Current Time is : {dateTimeNow}... </span>
  }
}

 

JSX의 속성 사용

class Profile extends React.Component {
  render () {
    return <a href={this.props.url}>{this.props.userName}</a>
  }
}


const el =document.getElementById('content')
var root = ReactDOM.createRoot(el)

root.render(
  <div>
    <HelloWorld></HelloWorld>
    <DateTimeNow></DateTimeNow>
    <Profile url="http://www.naver.com" userName="김만기"></Profile>
  </div>
)

 

JSX의 메소드 사용

class Profile2 extends React.Component {
  getUrl() {
    return 'http://www.naver.com'
  }
  render () {
    return <a className="block" href={this.getUrl()}>{this.props.userName}</a>
  }
}

 


https://github.com/Kmmanki/react_note/tree/master/chapter03

 

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

 

 

React 교과서 chapter02

엘리먼트의 중첩

const el =document.getElementById('content')
// 랜더링 할 root 태그 가져와서 React 객체로 생성
var root = ReactDOM.createRoot(el)

// h1 태그 생성
var h1 = React.createElement('h1', null, null, 'Hello World')

//div 태그 생성후 h1 태그를 복수개 append 
var div = React.createElement('div', null, null, h1, h1)

// root React 인스턴스 랜더링
root.render(div)

 

React 컴포넌트 클래스

  // 재사용할 태그 생성
  let h1 = React.createElement('h1', null, null, 'Hello World')

  // React.Component 를 상속
  class HelloWorld extends React.Component {
    render() {

      // 반환할 react Component 구성
      return React.createElement('div', null, h1, h1)
    }
  }


  const el =document.getElementById('content')
  var root = ReactDOM.createRoot(el)

  // 랜더링 할 Class를 React Component로 생성
  root.render(
    React.createElement(HelloWorld, null)
  )

 

리액트의 속성 사용

// 두번 째 인자는 해당 태그의 속성 값을 받을 수 있다.
let h1 = React.createElement('a', {href: 'http://naver.com'}, '네이버')

class HelloWorld extends React.Component {
  render() {
    return React.createElement('div', {id: 'test'}, h1)
  }
}


const el =document.getElementById('content')
var root = ReactDOM.createRoot(el)

root.render(
  React.createElement(HelloWorld, null)
)

 

props의 속성 사용

class HelloWorld extends React.Component {
  render() {
    // HelloWorld 컴포넌트를 사용하는 시점의 속성을 props로 사용 사용
    return React.createElement('a', {href: this.props.href}, '네이버')
  }
}


const el =document.getElementById('content')
var root = ReactDOM.createRoot(el)

root.render(
  // HelloWorld 컴포넌스 생성시 넘겨울 속성
  React.createElement(HelloWorld, {href: 'https://naver.com'})
)

 

props 모든 속성 사용

class HelloWorld extends React.Component {
  render() {
    //h1의 속성을 prop 받은 모든 속성.
    return React.createElement('h1', this.props, 'hello '+ this.props.title + ' world')
  }
}

const el =document.getElementById('content')
var root = ReactDOM.createRoot(el)

root.render(
  // 하위의 다른 HelloWorld를 감싸기 위한 div 를 구성
  React.createElement('div', null, 
    React.createElement(HelloWorld, {title:'React Framework', id: 'react'}),
    React.createElement(HelloWorld, {title:'Vue Framework', id: 'vue'})
  )
)

)

 


https://github.com/Kmmanki/react_note

 

GitHub - Kmmanki/react_note: 리액트 교과서 따라하기

리액트 교과서 따라하기. Contribute to Kmmanki/react_note development by creating an account on GitHub.

github.com

 

+ Recent posts