자식 컴포넌트를 만들어 사용하자

한 컴포넌트에 모든 UI 요소를 넣고 관리하는 것은 비효율 적이다.
다른 역할을 하는 각각의 로직은 별도로 분리해 자식 컴포넌트로 만들고,
그것을 부모 컴포넌트로 가져와 사용하는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
function Buttons() {
  return <button>Hello</button>; // 자식 컴포넌트를 만들고
}

function App() {
  <Button />; // 부모 컴포넌트에 넣어 사용
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);



부모가 자식에게 데이터를 보낼 수 있게하는 props

props는 부모 컴포넌트가 자식 컴포넌트에게 데이터를 보낼 수 있게하는 방식이다.
부모 컴포넌트에서 자식 컴포넌트 태그에 속성을 추가하고,
자식 컴포넌트 함수의 argument로 그 값을 받아와 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Buttons(props) {
  // 2. 자식 컴포넌트는 속성 오브젝트를 argument로 받아와서
  return <button>{props.btnName}</button>; // 사용
}

function App() {
  // 1. 부모 컴포넌트에서 속성과 값을 추가
  // 속성은 오브젝트의 형태로 저장되어 전달된다.
  <Button btnName="save" />;
  <Button btnName="reset" />;
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);

props를 받아올때 더 편리하게 사용하기 위해 props 오브젝트를 풀어서 사용한다.

1
2
3
function Buttons({ btnName }) {
  return <button>{btnName}</button>;
}

props를 활용하면 컴포넌트의 재사용성이 높아진다.
props를 활용해 UI의 스타일도 수정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Buttons({ btnName, big }) {
  return (
    <button
      style= {{
        padding: '16px 8px',
        border: 0,
        borderRadius: 8,
        fontSize: big ? 24 : 16 
      }}
    >
      {btnName}
    </button>
  );
}

function App() {
  <Button btnName="save" big="true" />;
  <Button btnName="Reset" big="false" />;
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);



props에 function도 넣어서 보낼 수 있다.

속성을 추가할때 넣은 onClick과, 속성을 받아와서 사용할때의 onClick을 구분하며 아래 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Buttons({btnName, onClick}) {
  return (
    <button onClick={onClick}>{btnName}</button>
    // 여기에 추가한 onClick은 진짜 이벤트리스너
  )
}

function App() {
  const [value, setValue] = React.useState('save') // string값을 state에 저장
  const changeValue = () => setValue('revert') // 값을 바꾸는 함수 생성
  return (
    <Buttons btnName={value} onClick={changeValue}/>
    // 속성의 값으로 함수도 넣을 수 있다.
    // 여기서 속성으로 추가한 onClick은 이벤트 함수가 아니다.
    <Buttons />
  )
}



불필요한 re-render를 막기위해 사용하는 React.memo()

부모 컴포넌트에서 state가 변경되면 그 안에 있는 자식 컴포넌트들은 모두 re-render 된다.
부모 컴포넌트에서 state에 변화가 일어날때 불필요한 re-render를 줄이기 위해 memo 메소드를 사용한다.
자식을 많이 가지고 있는 부모 컴포넌트에서 성능개선을 기대해볼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
function Buttons(props) {
  // code
}
const MemorizeBtn = React.memo(Buttons) // memo 메소드에 컴포넌트를 넣어서 사용

function App() {
  const [value, setValue] = React.useState('save')
  const changeValue = () => setValue('revert')
  <MemorizeBtn  btnName={value} onClick={changeValue}/> // 속성값이 바뀔때 리렌더
  <MemorizeBtn btnName='text'/> // 속성값이 바뀌지 않으면 리렌더되지 않음
}



props의 타입을 보호해주는 propTypes

내가 의도하지 않은 타입의 prop 값을 넘겨주는 오류를 막기위해 propTypes라는 패키지를 활용할 수 있다.
(하지만 런타임으로 타입 오류를 보여줌)

https://unpkg.com/prop-types@15.7.2/prop-types.js 로 패키지를 불러온다.

1
2
3
4
5
6
Buttons.propTypes = {
  text: PropTypes.string,
  fontSize: PropTypes.number.isRequired,
  // 이런식으로 자료의 타입을 지정할 수 있다.
  // 대문자 소문자 사용 실수에 유의하기
};



리액트 기본 수업만 듣고 중간에 타입스크립트를 배우러 갔다와서 복습중인데
덕분에 더 이해가 잘 되는 부분이 많아졌다!😘

Leave a comment