# 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 라고 부릅니다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simplereact.gitbook.io/simplereact/04.-state-props.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
