[Nomad coders] React - JSX, props

2020. 11. 8. 22:54Frontend/React

*foodILike array는 맨 밑에 첨부

  • 함수형 컴포넌트와 클래스형 컴포넌트 구분 : return과 render
  • array를 iter할 때 map()메서드를 사용
  • props의 타입 체크는 propTypes 메서드 사용
  • state를 직접 변경하면 render 호출에 문제 생기기 때문에, setState()를 사용하여 state를(데이터를) 변경해준다
class App extends Component {
  render() {
    return (
      <div>
        {/* map함수가 없었다면, 일일이 foodILike의 원소들을 기입해야한다.*/}
        {foodILike.map(dish => (
          <Food
            key={dish.id} // 고유성을 위해 key props를 넘겨주어야한다.
            name={dish.name}
            picture={dish.image}
            rating={dish.ratings} />
        ))}
      </div>
    );
  }
}
  • 여기서, dish는 임의로 지은 이름으로, foodILike 배열의 각 element를 한 번씩 방문하는 object
  • Food Component에서 key property는 추후에 추가한 것으로, 고유성을 전달하기 위해 필요한 인자
  • foodILike배열에 map()메서드를 사용한 덕분에, 한번에 배열의 원소들을 순회할 수 있다

propTypes: 컴포넌트의 props에서 타입을 체크하고싶다면 특별한 propTypes 속성을 할당

Food.propTypes = {
  name: propTypes.string.isRequired, // string 타입이 아닐시 에러메세지 
  picture: propTypes.string.isRequired, // isRequired: props가 전달이 안될 시 에러메세지
  ratings: propTypes.number.isRequired
}

함수형 컴포넌트, 클래스형 컴포넌트

  • 함수형 컴포넌트는 당연히 return이 필요하고, 클래스형 컴포넌트는 return 대신 render()메서드를 사용한다(함수가 아니니까 return이 필요없다)
함수형 컴포넌트
// App (부모)컴포넌트에서 받은 name과 picture, rating props들
// 함수형 컴포넌트
function Food({ name, picture, rating }) {
  return (
    <div>
      <h2>I like {name}</h2>
      <h3> {rating}/5.0 </h3>
      <img src={picture} />
    </div>
  );
}    
클래스형 컴포넌트
  • state를 직접 수정할 때 (권장 X)
    Do not mutate state directly. Use setState() <= 경고문 발생,
    setState()라는 메서드를 이용해서 state(데이터)를 바꿔주자.

왜냐하면 setState()를 사용하지 않으면, render()메서드가 새로 호출되지 않기 때문이다.
즉 setState()를 사용해야 render()가 반복적으로 작동한다.

class App extends Component { 
  // state는 변경될 수 있는 data를 넣을 수 있는 object. 그것이 state를 쓰는 이유
  state = {
    count: 0
  };   // we push the data into state object which want to be changed

  add = () => {
    this.state.count = 1; //Do not mutate state directly. Use setState() <= 경고문 발생, 
    }
  minus = () => {
    this.state.count = 1; //Do not mutate state directly. Use setState() <= 경고문 발생, 
  }
}
class App extends Component { 
  state = {
    count: 0
  };   

  add = () => {
    this.setState({ count: this.state.count + 1 }); // 이런식으로 state를 사용하는 것은 좋지 않기에, 아래 라인처럼 current를 사용
    this.setState(current => ({ count: current.count + 1 }))
  }
  minus = () => {
    this.setState(current => ({ count: current.count - 1 }))
  }

  // 매순간 내가 setState()를 호출할 때마다, react는 새로운 state와 함께 render method(이하)를 호출한다
  render() {   // render는 Component에서 땡겨온것이다
    return <div>
      <h1>
        {this.state.count}
      </h1>
      <button onClick={this.add}>ADD</button>
      <button onClick={this.minus}>MINUS</button>
    </div>
  }
}
const foodILike = [
  {
    ratings: 4.5,
    id: 1,
    name: "Kimchi",
    image:
      "http://aeriskitchen.com/wp-content/uploads/2008/09/kimchi_bokkeumbap_02-.jpg"

  },
  {
    ratings: 4.7,
    id: 2,
    name: "Samgyeopsal",
    image:
      "https://3.bp.blogspot.com/-hKwIBxIVcQw/WfsewX3fhJI/AAAAAAAAALk/yHxnxFXcfx4ZKSfHS_RQNKjw3bAC03AnACLcBGAs/s400/DSC07624.jpg"
  },
  {
    ratings: 5.0,
    id: 3,
    name: "Bibimbap",
    image:
      "http://cdn-image.myrecipes.com/sites/default/files/styles/4_3_horizontal_-_1200x900/public/image/recipes/ck/12/03/bibimbop-ck-x.jpg?itok=RoXlp6Xb"
  },
  {
    ratings: 4.0,
    id: 4,
    name: "Doncasu",
    image:
      "https://s3-media3.fl.yelpcdn.com/bphoto/7F9eTTQ_yxaWIRytAu5feA/ls.jpg"
  },
  {
    ratings: 4.2,
    id: 5,
    name: "Kimbap",
    image:
      "http://cdn2.koreanbapsang.com/wp-content/uploads/2012/05/DSC_1238r-e1454170512295.jpg"
  }
];