> For the complete documentation index, see [llms.txt](https://simplereact.gitbook.io/simplereact/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simplereact.gitbook.io/simplereact/04.-state-props.md).

# 04. State 와 Props

### 들어가기전

기존의 jQuery 와 다르게 React 에서는 DOM 에 직접적인 접근을 하여 DOM을 제어하지 않습니다.\
그 대신 State 라는 상태 값들을 이용하여 DOM 을 관리하고 변화시킵니다. \
\
State 는 내가 가진 값 ,Props 는 누구로부터 받는 값입니다. \
보통 부모 component 또는 뒤에서 배울 글로벌하게 상태를 관리 할 수 있게 도와주느 상태머신(Redux, Mobx, Context API 등..) 입니다.

### 실습

> 프로젝트는 [초기 세팅 상태](https://simplereact.gitbook.io/simplereact/02.-componet#undefined-1)로 진행되어집니다. +@ 로 이제는 styled-component 를 이용하기 때문에 App.css 파일이 필요없습니다.

Todo List 를 구성하려고합니다. 각 Todo 의 데이터 구조는 아래와 같습니다.&#x20;

```javascript
const Todo = {
  id: Date.now(), // 고유한 값을 주기 위해 사용합니다
  text: '리액트 공부하기',
  isDone: false // 완료 여부
}
```

Todo List 를 담을 State 를 추가합니다. State 를 추가하는 방법은 2 가지가 있습니다.

#### 컴포넌트를 만드는 방법&#x20;

State 를 알아보기전 Component 를 만드는 방법에 대해서 먼저 알아보려고합니다.\
Component 는 Class Component 와 Functional Component 2 가지의 종류가 있습니다.\
일반적으로 가장 많이 쓰이던 것이 아래에 있는 Class Component 였습니다.

```javascript
class App extends React.Component {} 
or 
class App extends React.PureComponent
```

[React Hooks](https://ko.reactjs.org/docs/hooks-intro.html) 라는 것이 나오면서 Class Component 보다는 Functional Component 가 더 많이 쓰이고 있는 추세입니다.\
아래와 같이 일반적인 function 같이 생긴 Component 들이 Functional Component 입니다.

```javascript
function App() {}
```

#### State

Class 와 Functional Component 는 State 를 선언하는 방법이 다릅니다.\
Class Component 부터 알아보도록 하겠습니다.

```javascript
// App.js 

import React from 'react';

class App extends React.Component {
  state = {
    todos: [
      {
        id: Date.now(),
        text: '리액트 공부하기',
        isDone: false
      }
    ]
  }
  render () {
    return (
      <div>{JSON.stringify(this.state.todos)}</div>
    )
  }
}
export default App;
```

위의 코드에서 보시면 `state = {}` 와 같이 state 를 선언하는 것을 확인 할 수 있습니다.\
선언된 state 는`this.state` 로 접근 할 수 있습니다.\
이 처럼 내가 가진 data 값을 State 라고 표현합니다.

하지만 Functional Component 에서는 `state = {}` 와 같은 표현을 사용 할 수 없습니다.\
Hooks 라는 것을 이용하여 State 를 선언합니다.

Hooks 에는 많은 종류의 Hook 들이 있습니다. 우리가 지금 하고자 하는것은 State 를 선언하는 것이기 때문에 `useState` 라는 Hook 만 이용해보겠습니다.

useState 는 아래와 같이 사용합니다.

```javascript
const [state name, set state] = useState(Initial value)
```

위의 사용법을 바탕으로 Class Component 에서 사용한 State 와 같이 구성을 해보겠습니다.

```javascript
// App.js 

import React, { useState } from 'react';

function App (){
  const [todos, setTodos] = useState([
    {
      id: Date.now(),
      text: '리액트 공부하기',
      isDone: false
    }
  ])
  
  return (
    <div>{JSON.stringify(todos)}</div>
  )
}
export default App;
```

좀 더 간단해보이지 않나요 ?&#x20;

#### Props&#x20;

이번에는 Props 에 대해서 학습해보겠습니다. 일단 Header Component 를 만들어보겠습니다.

```javascript
// src/components/header.js

import React from 'react'

class Header extends React.Component {
  render () {
    return (
      <div>
        Header
      </div>
    )
  }
}

export default Header
```

App.js 에서 Header Component 를 불러옵니다.

```javascript
// App.js

import React from 'react'
import Header from './components/header'

class App extends React.Component {
  render () {
    return (
      <div>
        <Header />
      </div>
    )
  }
}

export default App
```

![](/files/-LnlytCJTESATuWFLQEb)

하고자 하는것을 결론부터 말씀드리면 App.js 즉 부모 Component 에서 state 로 title 값을 가지고 있고, 이 값을 자식 Component 인 Header 에게 Props 로 전달하고자 합니다.

먼저 App.js 에 state 를 추가하겠습니다.

```javascript
// App.js

import React from 'react'
import Header from './components/header'

class App extends React.Component {
  state = {
    title: 'Props 알아보기'
  }
  
  render () {
    return (
      <div>
        <Header />
      </div>
    )
  }
}

export default App
```

그리고 해당 state 값을 Header 에게 넘겨줍니다.

```javascript
// App.js

<Header title={this.state.title} />
```

이렇게 되었을 때 Header 입장에서 저 title 값은 Props 라는 것은 부모로부터 받은 값 즉 Props 라는 것으로 판단되어집니다.

\
그러면 넘겨준 title 값을 Header 에서 받아보겠습니다.

```javascript
// src/components/header.js

import React from 'react'

class Header extends React.Component {
  constructor(props) { // props 에 접근하기 위해서 필요합니다.
    super(props)
  }
  render () {
    console.log(this.props)
    return (
      <div>
        Header
      </div>
    )
  }
}

export default Header
```

![](/files/-Lnm-4FapJ5bF3QAQ-4Q)

`this.props` 를 이용하여 props 에 접근 할 수 있습니다.

```javascript
// src/components/header.js

import React from 'react'

class Header extends React.Component {
  constructor(props) {
      super(props)
  }
  render () {
    return (
      <div>
        <h1>{this.props.title}</h1>
      </div>
    )
  }
}

export default Header
```

#### Functional Component Props&#x20;

Functional Component 에서는 Props 를 받는 방법이 다릅니다.

```javascript
// src/components/header.js

import React from 'react'

function Header(props) {  
    console.log(props) // { title: 'Props 알아보기'}
    const { title } = props // 또는 이런식으로 접근이 가능합니다.
    return (
        <div>
          {props.title}
          {title}
        </div>
    )
}

export default Header
```

function 의 인자값으로 Props 가 넘어오기 때문에 위처럼 접근 할 수 있습니다. \
또는 해체 할당자를 이용하여 아래와 같이 접근 할 수 있습니다.

```javascript
function Header({ title }) { // ... }
```

![](/files/-Lnm-LyC_Kh9REFEbxts)

#### Props 를 이용하여 Styled-Component 만들어보기&#x20;

Styled-Component 도 하나의 Component 입니다. 여러가지 값을 Props 로 넘겨주며 다양하게 Component 를 구성할 수 있습니다.

높이, 넓이, 색상 값을 외부에서 받아 구성하는 Box Component 를 만들어보겠습니다.\
App.js 에 Box 를 만들기 위한 State 를 추가합니다.

```javascript
// App.js 

import React from 'react'

class App extends React.Component {
  state = {
    wdith: 100,
    height: 100,
    color: '#00eaff'
  }

  render () {
    return (
      <div></div>
    )
  }
}

export default App
```

그 후 Box Component 를 만들어보겠습니다.\
Box 는 넓이, 높이, 색상을 Props 로 받습니다. Functional Component 에서 해체 할당으로 Props 를 받았던 것 처럼 여기서도 비슷하게 해체할당으로 받을 수 있습니다.

넓이, 높이 값이 넘어오지 않는다면 기본적으로 100px 으로 색상이 넘어오지 않는다면 하얀색으로 설정합니다.

```javascript
// App.js

const Box = styled.div`
  width: ${({ width }) => width || 100}px;
  height: ${({ height }) => height || 100}px;
  background-color: ${({ color }) => color || '#fff'};
`
```

이제 State 를 Box Component 에게 넘겨주면 됩니다.

```javascript
// App.js

import React from 'react'
import styled from 'styled-components'

const Box = styled.div`
  width: ${({ width }) => width || 100}px;
  height: ${({ height }) => height || 100}px;
  background-color: ${({ color }) => color || '#fff'};
`

class App extends React.Component {
  state = {
    wdith: 100,
    height: 100,
    color: '#00eaff'
  }

  render () {
    const { wdith, height, color } = this.state 

    return (
      <div>
        <Box wdith={wdith} height={height} color={color} />
      </div>
    )
  }
}

export default App
```

위처럼 Props 를 이용하면 다양하게 Style 을 적용할 수 있습니다.

![](/files/-Lnr2optWE5pQznm7-mO)

이 처럼 나의 값은 State, 외부로부터 전달 받은 값은 Props 라고 부릅니다.
