☭DEVELOPER/#2 웹개발(자바기반 풀스택)

[FRONTEND]리액트 JSX와 컴포넌트2

조반짝 2023. 10. 18. 17:22
728x90
반응형

// JSX는 JavaScript XML의 줄임말로 '자바스크립트에 XML을 추가한 확장형 문법'입니다.
// 앞서 src폴더안에 App.js을 다음의 내용으로 코딩하고 yarn start 실행 확인해 보시기 바랍니다.
import React from "react";
// 03폴더에 새로 작성한 TodaysPlan 컴포넌트를 불러들입니다.
import TodaysPlan from './03/TodaysPlan';
// Import문에서 파일 이름의 확장자 js 또는 jsx가 생략된 이유
// create-react-app은 js 또는 jsx 파일의 확장자를 생략해도 해당 파일을 자동으로 찾을 수 있게 설정되었습니다.
// 이렇게 자동으로 임포트할 수 있는 이유는 '웹팩 코드 검색 확장자(webpack modul resolution)' 기능 덕분입니다.
// 웹팩은 임포트된 파일을 분석하여 하나의 자바스크립트 파일을 생성할 때 파일 위치를 검색합니다. 이때 확장자 기능을 참조합니다. 
// 다음은 create-react-app의 웹팩 코드 검색 확장자의 파일 검색 순서를 나타냅니다.
// 1. 확장자가 파일 이름에 잇는 파일을 먼저 임포틓합니다.
// 2. 확장자가 파일 이름에 없는 경우 웹팩의 확장자 옵션(extentions)에 정의된 확장자 목록을 보고
//    해당 확장자 이름을 포함한 파일이 있는지 확인하여 임포트합니다.
//    예를 들어, import 'MyFile';의 경우, MyFile.js > MyFile.jsx 순서로 파이을 확인하여 임포트합니다.
// 3. 만약 지정 경로에 해당 파일이 없으면 같은 이름의 폴더는 없는지 검색합니다.
//    같은 이름의 폴더가 있다면 그 안에 있는 index 파일을 검색합니다.
//    예를 들어, import 'MyComponent';의 경우 MyComponent.js > MyComponent.jsx 순서로 확인합니다.
//    파일이 없으면 MyComponent 폴더를 검색하고 해당 폴더가 있는 경우 폴더 안에서 index.js > index.jsx 순서로 파일을 확인하여 임포트합니다.
// 컴포넌트 주요 구성 요소는 데이터 구성요소 기준 프로퍼티(상위 컴포넌트에서 하위 컴포넌트로 전달되는 읽기 전용 데이터입니다),
// state(컴포넌트의 상태를 저장하고 변경할 있는 데이터입니다), 컨텍스트(부모 컴포넌트에서 생성하여 모든 자식 컴포넌트에 전달하는 데이터입니다)

 

// rcc 입력 후 Tab키를 누르면 파일 이름에 맞게 클래스형 컴포넌트의 뼈대가 만들어집니다.
// 다음은 필수 리액트 구동 모듈입니다.

 // return문으로 JSX를 작성한 다음 저장하면 첫 번째 컴포넌트 작성이 끝납니다
    // 이때, 기존의 HTML 마크업과 구분하기 위해 컴포넌트 이름의 첫 번째 글자를 대문자로 해야 합니다.
    // 작성한 컴포넌트를 App 컴포넌트에 추가하겠습니다.

TodaysPlan 이 임포트 되어있다.

터미널에 리액트 구동하기

cd react_study/third_react

npm start

jsx 에다가 자바스크립트를 연계할 수 있고 컴퍼넌트들을 합쳐서 표현하다.

 

boolean 컴퍼넌트

      // 03폴더 BooleanComponent에서
      // const message = this.props.bored
      // ? "놀러 가자"
      // : "하던 일 열심히 마무리하기";
      // 실행 결과를 보면 프로퍼티의 이름만 전달한 경우에는 '놀러 가자'라는 문장이,
      // 프로퍼티의 이름을 전달하지 않은 경우에는 '하던 일 열심히 마무리하기'가 출력됩니다.
      // 이 방법은 실무에서 자주 사용하므로 꼭 알아두시기 바랍니다.

 

// 프로퍼티는 상위 컴포넌트가 하위 컴포넌트에 값을 전달할 때 사용합니다
// 이때, 프로퍼티값은 수정할 수 없다는 특징이 있습니다.
// 프로퍼티에 문자열을 전달할 때는 큰따옴표(" ")를 사용합니다
// 하지만, 숫자형이나 불리언 등의 값을 전달할 때는 큰 따옴표를 사용할 수 없습니다.
// 예를들어 value="123"이나 value="true"와 같은 방법으로 숫자형이나 불리언값을
// 프로퍼티에 전달하면 그냥 문자열로 인식됩니다.
// 리액트에서 문자열 외의 값은 따옴표 대신 중괄호({ })를 사용해야 합니다.

앱에 자식컴포넌트를 만들어주었다.

// 불리언 프로퍼티를 사용할 경우, 불리언은 true 또는 false만 정의할 수 있는 특수한 자료형입니다
// 불리언값은 true의 경우 프로퍼티 이름만 선언해도 전달할 수 있습니다. <ChildComponent boolValue />
// 불리언값의 false는 이름을 생략하면 됩니다. 불리언 프로퍼티에 false를 전달할 경우, <ChildComponent />

리액트 개발자로 컴포넌트의 상태를 알 수 있다.

bored 속성을 할 수있다(true/false)

statement에 대한 이해

// 앞서 03폴더에 있는 StateExample.jsx 내용을 App 컴포넌트에 넣어 render() 함수로 화면에 그려보겠습니다.
// 4초 뒤에 state에 저장된 값이 바뀌며 화면에 반영됩니다.
// 즉, 결과를 보면 화면이 4초 뒤에 바뀝니다. 프로퍼티에서 단순히 값을 읽어 화면에 출력한 것과 비교해 보면
// state의 유용함을 경험할 수 있습니다. 다만, 다음의 3가지 state 사용 주의 사항을 체크해야 합니다.
// 1. 생성자(constructor)에서 반드시 초기화해야 합니다.
// 2. state값을 변경할 때는 setState()함수(상태 관리 함수)를 반드시 사용해야 합니다.
// 3. setState() 함수는 비동기로 처리되며, setState()코드 이후로 연결된 함수들의 실행이 완료된 시점에
//    화면 동기화 과정을 거칩니다.
// state에 저장되는 객체는 반드시 초기화해야 합니다. 그렇지 않으면 내부 함수에서 state값에 접근할 수 없습니다.
// 만약 마땅한 초깃값이 없다면 state에 빈 객체라도 넣어야 합니다(this.state={ };)
// 그리고, state에 저장되는 객체의 값은 직접 변경하면 안됩니다.

// 앞서 프로퍼티의 경우, 컴포넌트 내부에서 값을 바꿀 수 없는 특징을 갖고 있었습니다
// 하지만, 쇼핑몰에서 물건 수량을 입력하거나 상품에 댓글을 남기는 등 '값을 바꿔야 하는 경우'가 발생할 수 있기에,
// 이럴 경우에는 state를 사용하여 컴포넌트의 상태를 관리할 수 있습니다.
// state는 '값을 저장하거나 변경할 수 있는 객체'로 보통 버튼을 클릭하거나 값을 입력하는 등의 이벤트와 함께 사용합니다.
// 예를 들어, 어떤 버튼을 눌렀을 때, 버튼 색을 변경하거나 글씨 모양을 바꿀 때 사용합니다.
// 다음은 state를 사용하여 setTimeout()함수를 통해 4초 후 state에 저장되어 있는 값을 변경하는 예제입니다
// 03폴더에 StateExample 컴포넌트를 만들어 다음 소스를 코딩합니다.

// 앞서 프로퍼티의 경우, 컴포넌트 내부에서 값을 바꿀 수 없는 특징을 갖고 있었습니다
// 하지만, 쇼핑몰에서 물건 수량을 입력하거나 상품에 댓글을 남기는 등 '값을 바꿔야 하는 경우'가 발생할 수 있기에,
// 이럴 경우에는 state를 사용하여 컴포넌트의 상태를 관리할 수 있습니다.
// state는 '값을 저장하거나 변경할 수 있는 객체'로 보통 버튼을 클릭하거나 값을 입력하는 등의 이벤트와 함께 사용합니다.
// 예를 들어, 어떤 버튼을 눌렀을 때, 버튼 색을 변경하거나 글씨 모양을 바꿀 때 사용합니다.
// 다음은 state를 사용하여 setTimeout()함수를 통해 4초 후 state에 저장되어 있는 값을 변경하는 예제입니다
// 03폴더에 StateExample 컴포넌트를 만들어 다음 소스를 코딩합니다.
import React, { Component } from 'react';

class StateExample extends Component {

    constructor(props){
        super(props);
        // state(상태) 정의
        // 컴포넌트에서 관리하려는 변수 state 초깃값을 this.state에 객체 형태로 정의합니다.
        this.state = {
            loading: true,
            formData: 'no data'
        };
        // 이후 콜백 함수를 다룰때 bind(this)를 선언하는 부분에 대해 다룹니다
        // 함수로 넘어갈 this는 반드시 생성자에서 bind()함수로 묶어주어야 합니다.
        // 즉, bind()함수로 묶어서 넘겨줘야 합니다.
        this.handleData = this.handleData.bind(this)
        // 생성 후 4초 후에 handleData 함수를 호출합니다.
        // setTimeout() 함수를 사용하여 4초 후에 handleData()함수를 호출합니다.
        setTimeout(this.handleData, 4000);
    }
    handleData(){
        const data = 'new data';
        //컴포넌트 특수 변수 this.state를 사용하여 state 값에 접근합니다.
        const{formData} = this.state;
        // state(상태) 변경
        // 컴포넌트의 내장 함수 this.setState()를 사용하여 state 값을 변경합니다.
        this.setState({
            loading: false,
            formData: data
        });
        // this.state.loading 은 현재 true 입니다.
        // 이후 호출될 출력 함수에서의 this.state.loading은 false입니다.
    }

    render() {
        return (
            <div>
                
            </div>
        );
    }
}

export default StateExample;

에러가 뜬다

<App.js>

// 앞서 03폴더에 있는 StateExample.jsx 내용을 App 컴포넌트에 넣어 render() 함수로 화면에 그려보겠습니다.
// 4초 뒤에 state에 저장된 값이 바뀌며 화면에 반영됩니다.
// 즉, 결과를 보면 화면이 4초 뒤에 바뀝니다. 프로퍼티에서 단순히 값을 읽어 화면에 출력한 것과 비교해 보면
// state의 유용함을 경험할 수 있습니다. 다만, 다음의 3가지 state 사용 주의 사항을 체크해야 합니다.
// 1. 생성자(constructor)에서 반드시 초기화해야 합니다.
// 2. state값을 변경할 때는 setState()함수(상태 관리 함수)를 반드시 사용해야 합니다.
// 3. setState() 함수는 비동기로 처리되며, setState()코드 이후로 연결된 함수들의 실행이 완료된 시점에
//    화면 동기화 과정을 거칩니다.
// state에 저장되는 객체는 반드시 초기화해야 합니다. 그렇지 않으면 내부 함수에서 state값에 접근할 수 없습니다.
// 만약 마땅한 초깃값이 없다면 state에 빈 객체라도 넣어야 합니다(this.state={ };)
// 그리고, state에 저장되는 객체의 값은 직접 변경하면 안됩니다.

import React, { Component } from "react";
import StateExample from './03/StateExample';

class App extends Component {
  render() {
    return (
     
      <div>
       <StateExample />

      </div>
    );
  }
}

export default App;

<StateExample.jsx>

// 앞서 프로퍼티의 경우, 컴포넌트 내부에서 값을 바꿀 수 없는 특징을 갖고 있었습니다
// 하지만, 쇼핑몰에서 물건 수량을 입력하거나 상품에 댓글을 남기는 등 '값을 바꿔야 하는 경우'가 발생할 수 있기에,
// 이럴 경우에는 state를 사용하여 컴포넌트의 상태를 관리할 수 있습니다.
// state는 '값을 저장하거나 변경할 수 있는 객체'로 보통 버튼을 클릭하거나 값을 입력하는 등의 이벤트와 함께 사용합니다.
// 예를 들어, 어떤 버튼을 눌렀을 때, 버튼 색을 변경하거나 글씨 모양을 바꿀 때 사용합니다.
// 다음은 state를 사용하여 setTimeout()함수를 통해 4초 후 state에 저장되어 있는 값을 변경하는 예제입니다
// 03폴더에 StateExample 컴포넌트를 만들어 다음 소스를 코딩합니다.
import React, { Component } from 'react';


class StateExample extends Component {

    constructor(props){
        super(props);
        // state(상태) 정의
        // 컴포넌트에서 관리하려는 변수 state 초깃값을 this.state에 객체 형태로 정의합니다.
        this.state = {
            loading: true,
            formData: 'no data'
        };
        // 이후 콜백 함수를 다룰때 bind(this)를 선언하는 부분에 대해 다룹니다
        // 함수로 넘어갈 this는 반드시 생성자에서 bind()함수로 묶어주어야 합니다.
        // 즉, bind()함수로 묶어서 넘겨줘야 합니다.
        this.handleData = this.handleData.bind(this)
        // 생성 후 4초 후에 handleData 함수를 호출합니다.
        // setTimeout() 함수를 사용하여 4초 후에 handleData()함수를 호출합니다.
        setTimeout(this.handleData, 4000);
    }
    handleData(){
        const data = 'new data';
        //컴포넌트 특수 변수 this.state를 사용하여 state 값에 접근합니다.
        const{formData} = this.state;
        // state(상태) 변경
        // 컴포넌트의 내장 함수 this.setState()를 사용하여 state 값을 변경합니다.
        this.setState({
            loading: false,
            formData: data
        });
        // this.state.loading 은 현재 true 입니다.
        // 이후 호출될 출력 함수에서의 this.state.loading은 false입니다.
    }

    render() {
        return (
            <div>
                {/* state(상태) 데이터는 this.state로 접근 가능합니다.*/}
                <span>로딩중: {String(this.state.loading)}</span>
                <br />
                <span>결과 : {this.state.formData}</span>
            </div>
        );
    }
}

export default StateExample;

COUNTER, RECOUNTER

// 리액트 생명주기 함수 사용 : 카운터 프로그램 코딩
// 다음은 부모 컴포넌트부터 count의 초깃값을 전달받아 숫자를 증가하는 카운터 프로그램입니다.
// 여기서는 getDerivedStateFromProps() 함수의 동작 원리도 알아보기 위해
// 2가지의 컴포넌트를 만들어 state에 저장되는 값을 변경해 봅니다.
// 다음과 같이 Counter 컴포넌트를 코딩해 봅니다.
// 코드를 보면 state의 초깃값을 설정할 때 props.count와 같이 프로퍼티로 받은 값을 사용합니다.

 

// constructor(props) 함수는 이름 그대로 '맨 처음에 생성될 때 한 번만 호출'되며,
  // 상태(state 또는 객체 변수)를 선언할 때 사용됩니다.
  // constructor()함수를 정의할 때는 항상 super()함수를 가장 위에 호출해야 합니다.
  // super()함수에는 프로퍼티와 생명 주기 상태 등을 초기화하는 중요한 과정을 포함하기 때문입니다.

// 리액트 생명주기 함수 사용 : 카운터 프로그램 코딩
// 다음은 부모 컴포넌트부터 count의 초깃값을 전달받아 숫자를 증가하는 카운터 프로그램입니다.
// 여기서는 getDerivedStateFromProps() 함수의 동작 원리도 알아보기 위해
// 2가지의 컴포넌트를 만들어 state에 저장되는 값을 변경해 봅니다.
// 다음과 같이 Counter 컴포넌트를 코딩해 봅니다.
// 코드를 보면 state의 초깃값을 설정할 때 props.count와 같이 프로퍼티로 받은 값을 사용합니다.
import React, { Component } from 'react';

class Counter extends Component {
  // constructor(props) 함수는 이름 그대로 '맨 처음에 생성될 때 한 번만 호출'되며,
  // 상태(state 또는 객체 변수)를 선언할 때 사용됩니다.
  // constructor()함수를 정의할 때는 항상 super()함수를 가장 위에 호출해야 합니다.
  // super()함수에는 프로퍼티와 생명 주기 상태 등을 초기화하는 중요한 과정을 포함하기 때문입니다.
  constructor(props) {
    super(props);
    this.state = {
        // count 초깃값을 프로퍼티에서 전달된 값으로 설정합니다.
        count: props.count
    };
    this.increaseCount = this.increaseCount.bind(this);
  }
  increaseCount(){
    this.setState(({count}) => ({conut: count +1}));
  }
    render() {
        return (
            <div>
                현재카운트 : {this.state.count}
                <button onClick={this.increaseCount}>카운트 증가</button>
            </div>
        );
    }
}

export default Counter;

여기서 잠깐!!

jsx 파일을 만들떄 class 와 비슷한 역할이기때문에 대소문자 구분해서 파일 생성해야한다.

// NewCounter 컴포넌트 소스 코딩
// 앞서, Counter 컴포넌트 소스 코딩 후에 NewCounter 컴포넌트를 소스 코딩합니다.
// 코드를 보면 getDerivedStateFromProps()함수를 사용하여 변경된 프로퍼티값으로 state값을 갱신합니다.

  // static getDerivedStateFromProps(props, state)함수
  // getDerivedStateFromProps()함수는 정적 함수입니다.
  // 따라서, 함수 안에서 this.props나 this.state와 같은 방법으로
  // 프로퍼티나 state값에 접근할 수 없습니다.
  // 만약, 각 값에 접근해야 하는 경우 반드시 인자로 전달된 props, state를 이용해야 합니다.
  // 이때 props는 상위 컴포넌트에서 전달된 값이며, state는 현재 컴포넌트의 state값입니다.
  // 이 함수는 상위 컴포넌트에서 전달받은 프로퍼티로 state값을 연동할 때 주로 사용되며,
  // 반환값으로 state를 변경합니다.

// NewCounter 컴포넌트 소스 코딩
// 앞서, Counter 컴포넌트 소스 코딩 후에 NewCounter 컴포넌트를 소스 코딩합니다.
// 코드를 보면 getDerivedStateFromProps()함수를 사용하여 변경된 프로퍼티값으로 state값을 갱신합니다.
import React, { Component } from 'react';

class NewCounter extends Component {

    constructor(props){
       super(props);
       this.state = {};
       this.increaseCount = this.increaseCount.bind(this); 
    }
    // static getDerivedStateFromProps(props, state)함수
    // getDerivedStateFromProps()함수는 정적 함수입니다.
    // 따라서, 함수 안에서 this.props나 this.state와 같은 방법으로
    // 프로퍼티나 state값에 접근할 수 없습니다.
    // 만약, 각 값에 접근해야 하는 경우 반드시 인자로 전달된 props, state를 이용해야 합니다.
    // 이때 props는 상위 컴포넌트에서 전달된 값이며, state는 현재 컴포넌트의 state값입니다.
    // 이 함수는 상위 컴포넌트에서 전달받은 프로퍼티로 state값을 연동할 때 주로 사용되며,
    // 반환값으로 state를 변경합니다.
    static getDerivedStateFromProps(props, state){
        const {count} = props;
    return{
        // 프로퍼트에서 전달된 count 값을 보관합니다.
        count,
        newCount:
        count === state.count
        ? // count 프로퍼티가 변경되지 않으면 기존 state 값으로 설정합니다.
        state.newCount
        : // 프로퍼티가 변경되었다면 변경된 프로퍼티 값으로 설정합니다.
        count // 조건 연산식 => A ? B : C
        };
    }

    increaseCount(){
        this.setState(({newCount}) => ({newCount: newCount + 1 }));
    }
    render() {
        return (
            <div>
               현재 카운트 : {this.state.newCount}
               <button onclick={this.increaseCount}>카운트 증가</button>

            </div>
            );
        }
    }
// APP 컴포넌트가 전달한 최초의 프로퍼티값은 state.count에 저장되며, NewCounter 컴포넌트는
// state.newCount로 증가값을 따로 분리하여 관리합니다. state.count가 아니라
// state.newCount로 증가값을 관리하는 이유는 getDerivedStateFromProps()함수는
// 다른 프로퍼티가 변경되어도 호출되기 때문입니다.
// count 프로퍼티가 변경되었는지 비교하려면 이처럼 값을 따로 관리해야 합니다.
export default NewCounter;

// 앞서 Counter 컴포넌트와 NewCounter 컴포넌트를 APP 컴포넌트에 포함시켜 화면에 출력해 봅니다.

props : 속성값 처리를 위해 사용

state: 속성값이 상태에따라 변화될때사용

this,state 그냥 솏겅값

setState: 변화된 속성값

// 앞서 Counter 컴포넌트와 NewCounter 컴포넌트를 APP 컴포넌트에 포함시켜 화면에 출력해 봅니다

import React, { Component } from "react";
import Counter from "./03/Counter";
import NewCounter from "./03/NewCounter";

class App extends Component {
  constructor(props){
    super(props);
    this.state = {count:10};
    this.resetCount = this.resetCount.bind(this);
  }
  resetCount(){
    this.setState(({count}) => ({count: count +10}));
  }
  render() {
    return (
    <div>
      <div>
       <Counter count={this.state.count}/>
      </div>
      <div>
       <NewCounter count={this.state.count}/>
      </div>
      <button onClick={this.resetCount}>
        {this.state.count + 10}으로 초기화
      </button>
    </div>
    );
  }
}
// 리액트 서버를 구동해 보면 두 컴포넌트 모두 APP 컴포넌트의 this.state.count로 프로퍼티를 초기화합니다.
// 즉, 동일한 숫자(10)부터 카운트하기 시작합니다.
// 두 컴포넌트 모두 [카운트 증가]버튼을 누르면 숫자가 1식 올라가며 정상적으로 작동합니다.
// 그런데 [20으로 초기화]버튼을 누르면 Counter컴포넌트의 숫자는 20으로 초기화되지 않습니다.
// NewCounter 컴포넌트만 getDerivedStateFromProps()함수로 APP 컴포넌트부터 갱신된 프로퍼티값을 동기화했기 때문입니다.
// Counter 컴포넌트는 처음 생성될 때만 프로퍼티값으로 state값을 설정하므로 갱신 과정에서는 state값이 변경되지 않습니다.
export default App;

// 리액트 서버를 구동해 보면 두 컴포넌트 모두 APP 컴포넌트의 this.state.count로 프로퍼티를 초기화합니다.
// 즉, 동일한 숫자(10)부터 카운트하기 시작합니다.
// 두 컴포넌트 모두 [카운트 증가]버튼을 누르면 숫자가 1식 올라가며 정상적으로 작동합니다.
// 그런데 [20으로 초기화]버튼을 누르면 Counter컴포넌트의 숫자는 20으로 초기화되지 않습니다.
// NewCounter 컴포넌트만 getDerivedStateFromProps()함수로 APP 컴포넌트부터 갱신된 프로퍼티값을 동기화했기 때문입니다.
// Counter 컴포넌트는 처음 생성될 때만 프로퍼티값으로 state값을 설정하므로 갱신 과정에서는 state값이 변경되지 않습니다.

<counter.jsx>

// 리액트 생명주기 함수 사용 : 카운터 프로그램 코딩
// 다음은 부모 컴포넌트부터 count의 초깃값을 전달받아 숫자를 증가하는 카운터 프로그램입니다.
// 여기서는 getDerivedStateFromProps() 함수의 동작 원리도 알아보기 위해
// 2가지의 컴포넌트를 만들어 state에 저장되는 값을 변경해 봅니다.
// 다음과 같이 Counter 컴포넌트를 코딩해 봅니다.
// 코드를 보면 state의 초깃값을 설정할 때 props.count와 같이 프로퍼티로 받은 값을 사용합니다.
import React, { Component } from 'react';

class Counter extends Component {
    // constructor(props) 함수는 이름 그대로 '맨 처음에 생성될 때 한 번만 호출'되며,
    // 상태(state 또는 객체 변수)를 선언할 때 사용됩니다.
    // constructor()함수를 정의할 때는 항상 super()함수를 가장 위에 호출해야 합니다.
    // super()함수에는 프로퍼티와 생명 주기 상태 등을 초기화하는 중요한 과정을 포함하기 때문입니다.

    constructor(props){
        super(props);
        this.state = {
            // count 초기값을 프로퍼티에서 전달된 값으로 설정합니다.
            count: props.count
        };
        this.increaseCount = this.increaseCount.bind(this);
    }
    increaseCount(){
        this.setState(({count}) => ({count: count + 1}));
    }

    render() {
        return (
            <div>
                현재 카운트 : {this.state.count}
                <button onClick={this.increaseCount}>카운트 증가</button>
            </div>
        );
    }
}

export default Counter;

<newcounter.jsx>

// NewCounter 컴포넌트 소스 코딩
// 앞서, Counter 컴포넌트 소스 코딩 후에 NewCounter 컴포넌트를 소스 코딩합니다.
// 코드를 보면 getDerivedStateFromProps()함수를 사용하여 변경된 프로퍼티값으로 state값을 갱신합니다.
import React, { Component } from 'react';

class NewCounter extends Component {
    constructor(props){
        super(props);
        this.state = {};
        this.increaseCount = this.increaseCount.bind(this);
    }
      // static getDerivedStateFromProps(props, state)함수
  // getDerivedStateFromProps()함수는 정적 함수입니다.
  // 따라서, 함수 안에서 this.props나 this.state와 같은 방법으로
  // 프로퍼티나 state값에 접근할 수 없습니다.
  // 만약, 각 값에 접근해야 하는 경우 반드시 인자로 전달된 props, state를 이용해야 합니다.
  // 이때 props는 상위 컴포넌트에서 전달된 값이며, state는 현재 컴포넌트의 state값입니다.
  // 이 함수는 상위 컴포넌트에서 전달받은 프로퍼티로 state값을 연동할 때 주로 사용되며,
  // 반환값으로 state를 변경합니다.
  static getDerivedStateFromProps(props, state){
    const {count} = props;
    return{
        // 프로퍼티에서 전달된 count값을 보관합니다.
        count,
        NewCount:
        count === state.count
        ? // count 프로퍼티가 변경되지않으면 기존 state값으로 설정합니다.
        state.NewCount
        : // 프로퍼티가 변경되었다면 변경된 프로퍼트값으로 설정합니다. 
        count
    };
  }

  increaseCount(){
    this.setState(({NewCount}) => ({NewCount: NewCount+1}));
  }

    render() {
        return (
            <div>
                현재 카운트 : {this.state.NewCount}
                <button onClick={this.increaseCount}>카운트 증가</button>
            </div>
        );
    }
}
// APP 컴포넌트가 전달한 최초의 프로퍼티값은 state.count에 저장되며, NewCounter 컴포넌트는
// state.newCount로 증가값을 따로 분리하여 관리합니다. state.count가 아니라
// state.newCount로 증가값을 관리하는 이유는 getDerivedStateFromProps()함수는
// 다른 프로퍼티가 변경되어도 호출되기 때문입니다.
// count 프로퍼티가 변경되었는지 비교하려면 이처럼 값을 따로 관리해야 합니다.
export default NewCounter;

ListExample

// 다음은 ListExample 컴포넌트의 가격표 목록을 출력하는 예제입니다.
// 배열 컴포넌트를 위한 map()함수의 활용 방법을 잘 알아두시기 바랍니다.
// 출력 결과는 App 컴포넌트에 ListExamlpe 컴포넌트를 import 하여 확인합니다.

 

// 다음은 ListExample 컴포넌트의 가격표 목록을 출력하는 예제입니다.
// 배열 컴포넌트를 위한 map()함수의 활용 방법을 잘 알아두시기 바랍니다.
// 출력 결과는 App 컴포넌트에 ListExamlpe 컴포넌트를 import 하여 확인합니다.

import React, { Component } from "react";

class App extends Component {
 
  render() {
    return (
    <div className="body">
      <ListExample/>
    </div>
    );
  }
}

export default App;

// 게시판이나 유튜브 영상 목록은 자바스크립트의 배열을 사용합니다.
// 자바스크립트 배열은 다음과 같이 다양한 자료형을 저장할 수 있습니다.
// [예시] const numberList = [1, 2, 3, 4, 5]; // 숫자형
// const mixedList = [1, 'str', {}, function a() {}]; // 2개 이상의 자료형
// 다양한 자료형을 저장할 수 있다는 성질을 이용하면 XML와 JSX도 배열에 저장할 수 있습니다.
// JSX 배열 저장 : const componentList = [<MyComponent />, <MySecondComponent />, <b>Hi</b>];

// 다음은 위의 방법을 활용하여 가격표 목록을 출력하는 예제입니다.
// 배열 컴포넌트를 위한 map()함수의 활용 방법을 잘 알아두시기 바랍니다.
// 출력 결과는 App 컴포넌트에 ListExampe 컴포넌트를 포함시켜 확인하시기 바랍니다.

to do list

      // render()함수는 데이터가 변경되어 새 화면을 그려야 할 때 자동으로 호출되는 함수입니다.
      // render()함수가 return 반환하는 JSX를 화면에 그려줍니다.
      // 아래의 내용이 JSX 양식 입니다.
      // 아울러, TodoList 컴포넌트를 JSX 안에 마크업 형식으로 추가했습니다.

// 배열 컴포넌트의 경우 배열 요소의 개수만큼 반복하므로 성능에 영향을 많이 줍니다.
// 따라서 배열 컴포넌트에는 키값을 key로 꼭 정의해 주어야 합니다.
// 키값을 정의하여 출력한 배열 컴포넌트는 다시 출력해야 하는 경우 리액트 엔진이
// 기존의 컴포넌트를 재활용하여 성능을 높일 수 있기 때문입니다.
// 다음은 키값을 정의한 배열 컴포넌트의 활용입니다.

todolist import하기 

 

728x90
반응형