개발/react

[React] 컴포넌트 분리와 props (+메서드 바인딩)

s2somang 2022. 3. 2. 00:26
인프런에 제로초님의 강의를 보고 정리한 내용입니다. 
[ 웹 게임을 만들며 배우는 React ]
https://www.inflearn.com/course/web-game-react

 

keymap에서 구현했던 코드를 조금더 가독성있게 만들어 보자 

 

<ul>
  {this.fruit.map((v , i) => ...

아래에 li로 반복문코드를 써주었던 부분을 따로 위에 뺄 수 있다. 

 fruit = [
    {fruit: "사과", taste :"맛있다"},
    {fruit: "배", taste :"달다"},
    {fruit: "바나나", taste :"맛없다"},
    {fruit: "포도", taste :"싫어"},
    {fruit: "딸기", taste :"좋아"},
  ];

조금더 가독성있는 코드가 되었다.  

 

 

여태까진 한두줄의 간단한 코드가 있었다면 

실무에서는 여러개의 코드가 기본..

아래와 같은 부분도 따로 파일로 빼줄 수 있다.! 

<li key = {b.fruit + v.taste}>
  <b>{v.fruit}</b> - {i}
  <div>컨텐츠1</div>
  <div>컨텐츠2</div>
  <div>컨텐츠3</div>
  <div>컨텐츠4</div>
</li>

 

Try.jsx파일을 만들어주자! (Try 컴포넌트)

import React , {Component} from 'react';

class Try extends Component {
    render() {
        return (
            <li>
                <b>{v.fruit}</b> - {i}
                <div>컨텐츠1</div>
                <div>컨텐츠2</div>
                <div>컨텐츠3</div>
              </li>
        )
    }
}
export default Try; //다른파일에서 불러올 수 있게 해주기!

 

 

매우 간단해졌다 

NumberBaseball.jsx

<ul>
  {this.fruit.map((v , i) => {
    return ( 
      <Try/>
    );
  })}
</ul>

 

컴포넌트를 분리해주는 이유

1. 가독성이 좋아진다. 

2. 성능최적화

3. 재사용성

코드가 길어진다면 컴포넌트로 분리해주자!

 

 

우리가Try로 바꾸면서 생기는 문제가 위에 map에서 만들어줌 v와 i를 사용할 수 없다. ㅜㅠ

이런 v와 i를 받아줄수있는 것이 바로 props!

사용하는 방법은 매우 간단하다

NumberBaseball.jsx

<Try value={v} index={i} />

v와 i가 value,index에 들어가서 사용할 수 있게 만들어준다. 

html에 속성을 지정해주는 것과 매우 비슷한데 

html에서는 attribute라면 리액트에서는 props라고 불린다.

 

따로뺀 파일로가서 this.props를 써주면 사용할 수 있다

Try.jsx

return (
<li>
    <b>{this.props.value.fruit}</b> - {this.props.index}
    <div>컨텐츠1</div>
    <div>컨텐츠2</div>
    <div>컨텐츠3</div>
</li>
)

 

 

이렇게 만드는게 익숙하지 않는다면 

일단 쭉 써준 후, 

새로운 컴포넌트를 만들어 기존 데이터를 props로 전달하는 과정을 하자!! = (탑다운방식)

 

 

이 상태로 실행해주면 역시나 key가 없다고 에러가 뜬다 ㅎ.

Warning: Each child in a list should have a unique "key" prop.

Try 안에 key를 써주쟈 map안에는 key를 반드시 써줘야함

<Try key={v.fruit + v.taste} value={v} index={i} />

고 유 하 게 ... 

 

고조할아버지에서 나에게 , 내가 증조할아버지에게 뭔가를 주고싶을때 사용하는것 -> 리덕스, 컨텍스트

 

jsx의 주석

리액트에서 주석처리는

{/* ... */ }

이렇게 {}로 감싸주는 형식이다. 

 

메서드 바인딩

사용자 정의 함수에서 () => {} 대신 () {} 이렇게 쓰면 this를 못쓰고 error가 나타남



 

 

전체코드(bind사용)

더보기
import React from "react";
import { Component } from "react";
import Try from './Try';

 

const getNumbers = () => {
// 숫자 네개를 곂치지 않고 랜덤하게 뽑는 함수
};

 

// 바뀌는 부분을 잘 생각해서 component를 만든다.
class NumberBaseball extends Component {
constructor(props){
super(props);
this.state = {
result: "",
value: "",
// 화면에 보이지는 않지만 해주어야할 것
// 숫자 4개를뽑아야함
anwser: getNumbers(),
tries: [],
};
this.onSubmitForm = this.onSubmitForm.bind(this);
this.onChangeInput = this.onChangeInput.bind(this);
}

 

 
onSubmitForm(e) {
e.preventDefault();
console.log(this.state.value);
};

 

onChangeInput(e) {
this.setState({
value: e.target.value,
})
};

 

fruits = [
{fruit: "사과", taste :"맛있다"},
{fruit: "배", taste :"달다"},
{fruit: "바나나", taste :"맛없다"},
{fruit: "포도", taste :"싫어"},
{fruit: "딸기", taste :"좋아"},
];

 

render() {
// state가 바뀔때마다 render안에가 재실행 됨~
return (
<>
<h1>{this.state.result}</h1>
<form onSubmit={this.onSubmitForm}>
<input
maxLength={4}
value={this.state.value}
onChange={this.onChangeInput}
/>
</form>
<div>시도 : {this.state.tries.length}</div>
<ul>
 
{this.fruits.map((v , i) => {
return (
<Try key={v.fruit + v.taste} value={v} index={i} /> /
);
})}
</ul>
</>
);
}
}
export default NumberBaseball; // import NumberBaseball;



 

전체코드(화살표함수 사용)

화살표 함수를 사용하면 bind를 사용하지 않아도 된나. 자동으로 된다.

더보기
import React from "react";
import { Component } from "react";
import Try from './Try';

const getNumbers = () => {
// 숫자 네개를 곂치지 않고 랜덤하게 뽑는 함수
};

// 바뀌는 부분을 잘 생각해서 component를 만든다.
class NumberBaseball extends Component {
state = {
result: "",
value: "",
// 화면에 보이지는 않지만 해주어야할 것
// 숫자 4개를뽑아야함
anwser: getNumbers(),
tries: [],
};
// this.onSubmitForm = this.onSubmitForm.bind(this);
// this.onChangeInput = this.onChangeInput.bind(this);


//화살표 함수를 사용하지 않으면 컨스트럭터를 다시 써야함. 지저분해짐
onSubmitForm = (e) => {
e.preventDefault();
console.log(this.state.value);
};

onChangeInput = (e) => {
this.setState({
value: e.target.value,
})
};

fruits = [
{fruit: "사과", taste :"맛있다"},
{fruit: "배", taste :"달다"},
{fruit: "바나나", taste :"맛없다"},
{fruit: "포도", taste :"싫어"},
{fruit: "딸기", taste :"좋아"},
];

render() {
// state가 바뀔때마다 render안에가 재실행 됨~
return (
<>
<h1>{this.state.result}</h1>
<form onSubmit={this.onSubmitForm}>
<input
maxLength={4}
value={this.state.value}
onChange={this.onChangeInput}
/>
</form>
<div>시도 : {this.state.tries.length}</div>
<ul>
{/* 반복되는 걸 배열로 만들자 */}
{this.fruits.map((v , i) => {// i index
// i는 고유함 절대 곂칠일이 없음.
// key에 i를 쓰면 나중에 성능최적화에 문제가 됨 차라이 v.fruit+i... 하지만 이것도 나쁜 방식
return (
<Try key={v.fruit + v.taste} value={v} index={i} /> // v와 i가 value,index에 들어감
// html에 속성 넣어주는 것과 비슷한데,
// html에서는 attribute ,리액트는 props임!
);
})}
</ul>
</>
);
}
}
export default NumberBaseball; // import NumberBaseball;