Props (불변값)

- React Component로 넘겨지는 속성 값 (상위 -> 하위)

- 변수에 넣어서 Component로 넘긴다고 생각

- Props 값은 변경 X

- 커스텀 태그의 속성을 사용하여 propsName = “value” 형태로 React Component로 넘김 

const myelement = <Car brand="Ford" />;

- Component에서는 {this.props.propsName} 으로 접근하여 넘겨받음

class Car extends React.Component {
  render() {
    return <h2>I am a {this.props.brand}!</h2>;
  }
}

- { this.props.children } : 커스텀 태그의 내용을 담고 있음. 내장되어 있음

class Car extends React.Component {
  render() {
    return <div>I am a {this.props.brand}!, {this.props.children}</div>;
  }
}

class Garage extends React.Component {
  render() {
    return (
      <div>
        <div>Who lives in my garage?</div>
        <Car brand="Ford">Hello</Car>
      </div>
    );
  }
}

ReactDOM.render(<Garage />, document.getElementById('root'));

or

class Car extends React.Component {
  render() {
    return <div>I am a {this.props.brand}!, {this.props.children}</div>;
  }
}

class Garage extends React.Component {
  render() {
    return (
      <div>
        <div>Who lives in my garage?</div>
        <Car brand={this.props.brand}>{this.props.children}</Car>
      </div>
    );
  }
}

ReactDOM.render(<Garage brand="Ford">Hello</Garage>, document.getElementById('root'));

결과 :

Who lives in my garage?
I am a Ford!, Hello

- 함수도 Props를 사용하여 하위 Component로 보낼 수 있음

class Car extends React.Component {

  _handleName(c) {
    const {setName} = this.props; 	/* 구조분해 */
    setName(c);				/* Garage의 _setName() 호출 */
  }
  
  render() {
    return (
      <div>I am a {this.props.brand}!, {this.props.children}</div>
      <button type="button" onClick={() => this._handleName(c)}>이름변경</button>
    )
  }
}

class Garage extends React.Component {
  _setName(nm) {
    this.setState({nm});
  }

  render() {
    return (
      <div>
        <div>Who lives in my garage?</div>
        <Car brand="Ford" setName={this._setName.bind(this)}>Hello</Car>   /* setName으로 Car로 넘어감 */
      </div>
    );
  }
}

ReactDOM.render(<Garage />, document.getElementById('root'));

→ Garage의 _setName()이 Car의 setName이라는 이름으로 props로 넘겨져서 _handleName() 에서 호출됨

● 기본값 설정 : defaultProps

class App extends React.Component {
  render() {
    return (
      <div>{this.props.value}</div>		/* 0 */
    )
  }
}

App.defaultProps = {
  value:0
}

● 타입 검증 : propTypes

class App extends React.Component {
  render() {
    return (
      <div>{this.props.value}</div>
      <div>{this.props.secondValue}</div>
      <div>{this.props.thirdValue}</div>
    )
  }
}

App.propTypes = {
  value: React.PropTypes.string
  secondValue: React.PropTypes.number
  thirdValue: React.PropTypes.any.isRequired
}

State (가변값)

- React Component에서 초기설정 후 동적 처리

- State 값은 변경 O -> this.setState() 사용

- Constructor(생성자)에서 this.state = {} 를 통해 초기값 설정

- state에 접근할 때 {this.state.stateName} 사용

- 랜더링 된 후 컴포넌트 내부에서 this.setState({…}) 를 사용하여 값을 변경함 (this.state 절대 사용 X)

class Car extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      brand: "Ford",
      model: "Mustang",
      color: "red",
      year: 1964,
      value: 0
    };
    this.handleClick = this.handleClick.bind(this)		/* 생성자에서 this 바인딩 */
  }
  
  changeColor = () => {
    this.setState({color: "blue"});
  }
  
  handleClick() {
    this.setState({
      value: this.state.value +1
    })
  }
  
  render() {
    return (
      <div>
        <h1>My {this.state.brand}</h1>
        <p>
          It is a {this.state.color}
          {this.state.model}
          from {this.state.year}.
        </p>
        <!-- 버튼 클릭시 state.color가 red -> blue로 변경 -->
        <button type="button" onClick={this.changeColor}>Change color</button> 
        
        <!-- 버튼 클릭시 value +1 -->
        <button type="button" onClick={this.handleClick}>plus count</button>
      </div>
    );
  }
}

- onclick이 아닌 카멜표기법으로 onClick를 사용해야 함

- this.changeColor()가 아닌 this.changeColor를 사용해야 함

- this는 본인 객체를 의미함 (여기서는 Car)