Learning React(3. React 속성 전달)

1. 속성 전달

  • 한 계층에서 컴포넌트 사이의 속성 전달은 간단하고 문제가 ㅇ벗지만 여러 계층에 걸쳐 컴포넌트 사이에 속성을 전달해야 하는 상황이라면 난이도가 올라간다
  • 이러한 접근 방법은 확장성도 없고 유지 보수도 어렵다
    • 전달해야 할 속성이 추가 또는 삭제 등을 할 때마다 각 컴포넌트의 선언부에 코드를 추가 또는 삭제해야 한다
    • 그리고 어느시점에 속성의 이름을 변경해야 한다면 전 컴포넌트에서도 해당하는 속성의 이름을 변경해야하는 번거로움이 있다

01. 문제점 분석

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React!</title>
  <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #EEE;
    }
  </style>
</head>

<body>
  <div id="container"></div>

  <script type="text/babel">
    var destination = document.querySelector("#container");

    class Display extends React.Component {
      render() {
        return (
          <div>
            <p>{this.props.color}</p>
            <p>{this.props.num}</p>
            <p>{this.props.size}</p>
          </div>
        )
      }
    }

    class Label extends React.Component {
      render() {
        return (
          <Display
            color={this.props.color}
            num={this.props.num}
            size={this.props.size}
          />
        )
      }
    }

    class Shirt extends React.Component {
      render() {
        return (
          <div>
            <Label
              color={this.props.color}
              num={this.props.num}
              size={this.props.size}
            />
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <div>
        <Shirt color="steelblue" num="3.14" size="medium" />
      </div>,
      destination
    );
  </script>
</body>

</html>


02. 스프레드 연산자(전개 연산자)와의 만남

  • ...를 앞에 사용

-1. 스프레드 연산자 예시

  • 배열 안의 개별 요소를 밖으로 풀어내는 역할을 한다
<script>
    var items = ["1", "2", "3"];

    function printArray(a, b, c) {
      console.log("print : " + a + " " + b + " " + c);
    }

    printArray(items[0], items[1], items[2]);

    // spread operator
    printArray(...items);
</script>

-2. 스프레드 연산자 활용

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React!</title>
  <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #EEE;
    }
  </style>
</head>

<body>
  <div id="container"></div>

  <script type="text/babel">
    var destination = document.querySelector("#container");

    class Display extends React.Component {
      render() {
        return (
          <div>
            <p>{this.props.color}</p>
            <p>{this.props.num}</p>
            <p>{this.props.size}</p>
          </div>
        )
      }
    }

    class Label extends React.Component {
      render() {
        return (
          <Display {...this.props} />
        )
      }
    }

    class Shirt extends React.Component {
      render() {
        
        return (
          
          <div>
            <Label {...this.props} />
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <div>
        <Shirt color="steelblue" num="3.14" size="medium" />
      </div>,
      destination
    );
  </script>
</body>

</html>


2. JSX와의 재회

01. JSX 간단 분석

  • JSX가 순수 자바스크립트로 트랜스파일링 된다

-1. JSX

class Card extends React.Component {
	render() {
		var cardStyle = {
		height : 200,
		width : 150,
		padding : 0,
		margin : 10,
		display : "inline-block",
		backgroundColor : "#FFF",
		boxShadow : "0px 0px 5px #666"
		};

	return (
		<div style={cardStyle}>
			<Square color={this.props.color} />
			<Label color={this.props.color} />
		</div>
		)
	}
}

-2. JavaScript

class Card extends React.Component {
	render() {
    	var cardStyle = {
        	height : 200
            , width : 150
            , padding : 0
            , backgroundColor : "#FFF"
            , boxShadow : "0px 0px 5px #666"
        };
        
        return React.createElement(
        	"div"
            , { style : cardStyle }
            , React.createElement(Square, { color : this.props.color })
            , React.createElement(Label, { color : this.props.color })
        );
    }
}

02. 중요한 JSX 특징

-1. 표현식 평가

  • JSX는 JavaScript처럼 취급 된다 즉 아래 코드와 같은 식으로 JSX가 정적 콘텐츠만을 다루게 제한돼 있지 않다는 의미
  • {}, 중괄호를 활용하여 다양한 표현을 출력할 수 있다
class Stuff extends React.Component {
	render() {
		return(
			<h1>Boring static content!</h1>
		)
	}
}

class Stuff extends React.Component {
	render() {
		return(
			<h1>Boring {Math.random() * 100} content!</h1>
		)
	}
}

-2. 복수의 엘리먼트 리턴

_1. 배열같은 식의 문법을 사용

  • 복수의 아이템을 리턴할 대 다룰 수도 있는 사항이 하나 있다, 바로 각 아이템에 key 속성과 고유의 값을 지정하는 일이다
    • key를 지정해 줌으로서 어떤 엘리먼트를 다뤄야 하는지 그리고 변경이 발생했는지 더 잘 이해할 수 있다
class Stuff extends React.Component {
	render() {
		return(
			[
			<p key="1">I am</p>,
			<p key="2">returning a list</p>,
			<p key="3">of thing!</p>
			]
		)
	}
}

_2. 프래그먼트(Fragments)

  • react v16.2.0부터 추가된 패턴
  • 1. React.Fragment 컴포넌트는 실제로 DOM 엘리먼트로 생성되지 않는다, 단지 HTML로 트랜스파일될 때 존재하지 않는 것으로 취급하라고 JSX에게 알려줄 뿐이다
  • 2. 아이템들이 배열에 담겨 리턴되는 것이 아니므로 쉼표나 다른 구분자가 필요 없다
  • 3. key 속성과 고윳값을 지정할 필요가 없다, 그와 관련된 모든 사항은 물티에서 알아서 관리된다
class Stuff extends React.Component {
	render() {
		return(
			<React.Fragment>
				<p key="1">I am</p>,
				<p key="2">returning a list</p>,
				<p key="3">of thing!</p>
			</React.Fragment>
		)
	}
}
  • <React.Fragment></React.Fragment> 대신 <></> 사용
class Stuff extends React.Component {
	render() {
		return(
			<>
				<p key="1">I am</p>,
				<p key="2">returning a list</p>,
				<p key="3">of thing!</p>
			</>
		)
	}
}

-3. 인라인 CSS 사용 불가

  • JSX에서는 style 속성 안에 직접 CSS를 포함할 수 없으며, 그 대신 아래 코드와 같이 스타일 정보를 담은 객체를 참조해야 한다
  • -대신에 카멜표기법으로 속성을 지정한다
class Card extends React.Component {
	render() {
		var cardStyle = {
			height : 200,
			width : 150,
			padding : 0,
			margin : 10,
			display : "inline-block",
			backgroundColor : "#FFF",
			boxShadow : "0px 0px 5px #666"
		};

		return (
		<div style={cardStyle}>
			<Square color={this.props.color} />
			<Label color={this.props.color} />
		</div>
		)
	}
}

-4. 주석

  • 주석은 한 가지를 제외하면 JS랑 흡사하다, 그 한가지는 태그의 자식 위치에 주석을 넣을 때, 아래와 같이 주석이 표현식으로 해석될 수 있게 중괄호로 감싸야 한다는 점이다
class Stuff extends React.Component {
	render() {
		return(
		<div>
			{/* 자식으로서의 주석*/}
		</div>
		)
	}
}

-5. 대소문자 구별

  • HTML 태그를 나타날 때는 소문자로 작성
class Stuff extends React.Component {
	render() {
		return(
		<div>
			<p>HTML TAG</p>
		</div>
		)
	}
}
  • 컴포넌트를 나타날 때는 그 이름에 대문자가 사용돼야 한다
class Stuff extends React.Component {
	render() {
		return(
		<div>
			<Letter/>
		</div>
		)
	}
}

03. 어디서든 가능한 JSX

  • 지금까지는 JSX 코드는 render나 return 함수 안에만 있었지만 아래와 같은 경우도 있다
var swatchComponent = <Swatch color="#2F004F"></Swatch>

ReactDOM.render(
	<div>
		{swatchComponent}
	</div>
	, document.querySelector("#container")
)

좋은 웹페이지 즐겨찾기