# 03. State 와 Props

## State 와 Props

기존의 jQuery 와 다르게 vue 는 document 에 직접적인 접근을 하여 DOM을 제어하지 않습니다.\
그대신 state 라는 상태를 이용하여 DOM 을 관리합니다. \
그렇다면 state 와 props 는 무엇일까요 ?\
쉽게 말씀드리자면 state 는 나의 data, props 는 누구로부터 받는 data 입니다. \
여기서 누구는 보통 부모 component 또는 뒤에서 배울 상태머신(vuex)입니다.

아직은 state 와 props 가 무엇인지 감이 안오실 수 있기 때문에 직접 실습을 하며 배워보도록 하겠습니다.

### State

**Box.vue** 라는 Box Component 가 있다고 예를 들어보겠습니다. \
박스는 **40** 이라는 **높이**를 가지고 있고, **80** 이라는 **높이** 값을 가지고 있습니다. \
이 값들은 어떠한 행동에 따라 변경 될 여지가 있는 값 이라고 할 때,  우리는 어딘가 이 값들을 가지고 있어야하고 이 값을 바탕으로 Box 를 그려줘야합니다.

**정리를 해보면 넓이 40, 높이 80 의 어떤 데이터를 Box.vue 는 가지고 있어야 된다는 것 입니다.**

> (예제는 [이전의](https://simplevue.gitbook.io/intro/02.-component#undefined-3) 구성되었던 환경에서 이어서 해도되고 새로 프로젝트를 구성하셔도 됩니다.)

### 실습 - state 다뤄보기

일단 Box component 를 만들어야합니다.

![Box.vue](https://3068925918-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYGyJlfT4aHSW1TgIhy%2F-LYliGJe44WNMLH1CZss%2F-LYljLN0Yo3A8FprbfmM%2Fimage.png?alt=media\&token=4bdbbb11-ac86-4c16-a5e5-064a175f0edd)

component 의 state 는 data 라는 함수를 이용하여 구성할 수 있습니다.

```javascript
// Box.vue 

<script>
export default {
  data() {  // Box 의 state
    return {
      width: 40, // 넓이
      height: 80 // 높이
    };
  }
};
</script>
```

**data** 안의 모든 값은 [Proxy](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Proxy) 로 변경에 대한 처리가 [observable](https://kr.vuejs.org/v2/guide/reactivity.html) 하게 이루어 집니다.

### State 를 이용하여 Style 적용하기

위에서 만들어 놓은 state 를 바탕으로 box 를 그려보겠습니다 :)

vue 에 관련된 무엇인가를 적용하기 위해서는 **v-bind** 라는 것을 이용해야합니다.\
html tag 에 인라인으로 스타일을 적용할 때는 **v-bind:style** 또는 v-bind 를 생략한 **:style** 를 이용합니다.

```javascript
<div v-bind:style="{color: #ebebeb}"></div>
<div :style="{color: #ebebeb}"></div>
```

box 에 state 값을 바탕으로 스타일을 적용해보겠습니다.

```javascript
// Box.vue 

<template>
  <div v-bind:style="{ width: width + 'px', height: height + 'px' }"></div>
</template>
```

스타일이 적용된걸 확인할 수 있습니다.

![](https://3068925918-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYGyJlfT4aHSW1TgIhy%2F-LYliGJe44WNMLH1CZss%2F-LYlkcmhs1zOoFiNrbha%2Fimage.png?alt=media\&token=efa19850-641a-4737-8428-40979c431a03)

class 를 추가하여서 border 를 추가해보겠습니다.

```javascript
// Box.vue 

<style scoped>
.box {
  border: 1px solid #000;
}
</style>
```

![](https://3068925918-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYGyJlfT4aHSW1TgIhy%2F-LYliGJe44WNMLH1CZss%2F-LYll3KVR2OV5MOLYybh%2Fimage.png?alt=media\&token=8ec4e2af-1bbc-46d9-ac07-3ccf62f1f081)

### Props&#x20;

우리는 여러개의 Box 를 만들고 싶어 졌습니다. 그래서 App.vue 에서 Box 여러개를 더 추가하였습니다.

```javascript
// App.vue 

<template>
  <div>
    <Box/>
    <Box/>
    <Box/>
    <Box/>
    <Box/>
    <Box/>
  </div>
</template>
```

![추가된 box](https://3068925918-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYGyJlfT4aHSW1TgIhy%2F-LYliGJe44WNMLH1CZss%2F-LYllqsNZ4BtZcCoRZ-d%2Fimage.png?alt=media\&token=3eec51ed-fc11-4db1-98ca-5fce768cd1e0)

박스별로 색상을 다르게 주고 싶어 졌습니다. Box.vue 에 색상 class 들을 추가해보겠습니다. class 가 변경됨에 따라 background 색상이 변경되도록 하겠습니다.

```javascript
// Box.vue 

<style scoped>
.box {
  border: 1px solid #000;
}
.blue {
  background: #009bff;
}
.purple {
  background: #8f46ff;
}
.green {
  background: #00bcac;
}
</style>
```

Box 별로 색상을 다르게 주기 위해서는 어떻게 하면될까요 ? 가장 간단한 방법은 Box component 를 사용하는 곳에서 Box component 로 사용할 color class 를 전달해주면 됩니다.&#x20;

```javascript
<Box color="blue"/>
```

위와 같이 전달해주기 위해서는 Box component 를 사용하고 있는 App.vue 에서 전달해야겠죠 :)&#x20;

```javascript
// App.vue 

<template>
  <div>
    <Box color="blue"/>
    <Box color="purple"/>
    <Box color="green"/>
    <Box color="blue"/>
    <Box color="purple"/>
    <Box />
  </div>
</template>
```

그렇다면 Box 에서는 부모 component 인 App.vue 에서 내려준 값 **(Box 입장에서는 이 값을 props 라고 부릅니다)** 을 어떻게 받을 수 있을까요?<br>

값을 받을 component 즉 Box.vue 에서 다음과 같이 props 를 이용하여 받을 수 있습니다.\
type 을 적어줌으로써 props 에 대한 안전함을 보장할 수 있습니다. \
해당 props 가 내려오지 않았을 경우를 방지하기 위해 default 값 또한 줄 수 있습니다.

```javascript
props: {
    color: { type: String, default: '' }
}
```

Box.vue 에 추가해보겠습니다.

```javascript
// Box.vue 

<script>
export default {
  props: {
    color: { type: String, default: "" }
  },
  data() {
    return {
      width: 40,
      height: 80
    };
  }
};
</script>
```

### Props 를 바탕으로 class bind 해보기

App.vue 에서 내려주는 color 라는 값을 받을 수 있게 되었습니다. 이제 내려 받은 값을 Box component 에 class 로 적용해주기만 하면 됩니다.\
props 나 state 를 바탕으로 class 를 적용해주기 위해서는 v-bind:class 또는 :class 를 이용해야 합니다.

```javascript
<div v-bind:class="[state, props]"></div>
<div :class="[state, props]"></div>
```

위의 내용을 바탕으로 Box 에 적용해보겠습니다.

```javascript
<template>
  <div 
    v-bind:class="['box', color]" 
    v-bind:style="{ width: width + 'px', height: height + 'px' }">
  </div>
</template>
```

![](https://3068925918-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LYGyJlfT4aHSW1TgIhy%2F-LYliGJe44WNMLH1CZss%2F-LYlpYglZAOgsn7Ywh1n%2Fimage.png?alt=media\&token=0c81eb0c-3e62-4ba6-8e64-528b0be11219)

내려받은 color props 를 바탕으로 Box 의 색상이 변경되었습니다. 맨 아래 있는 Box 는 Color 를 내려주지 않았기 때문에 default color 인 #fff 가 적용되었습니다.

### 마무리

**state, props** 에 대해서 알아봤습니다. 단일 component 를 사용해서 예제를 구성했기 때문에 어떨 때 state를 쓰고 어떨 때 props를 써야 할지 아직 감이 안 잡힐 수 있습니다 :) \
지금은 어떤 것이 state이고 어떤것이 props인지 아는 정도만 되어도 충분하다고 생각합니다.

proxy 로 알아보는 dom update: <https://stackblitz.com/edit/js-l7ifdm>\
&#x20;<br>


---

# 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://simplevue.gitbook.io/intro/03.-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.
