# 06. Event

### 들어가기전&#x20;

React 에서는 직접적인 DOM 의 접근보다는 State 라는 상태 값을 이용하여 DOM 에 변화를 준다고 했습니다. \
이번에는 Event 를 학습하여 State 를 다양하게 변경하는 방법에 대해서 알아보려고합니다.

### 실습

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

우리가 입력하는 값에 따라서 넓이, 높이, 색상을 가진 박스를 만들어보고자 합니다.

Input 에 값을 입력하여 입력된 값을 바탕으로 상자를 만들고 싶습니다.\
먼저 Input, Label Component 를 만들어보겠습니다.

```javascript
// App.js

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

const Label = styled.h2`
  color: #333;
`

const Input = styled.input`
  padding: 10px 20px;
`

class App extends React.Component {
  render () {
    return (
      <div>
        <Label>Width</Label>
        <Input />
        <Label>Height</Label>
        <Input />
        <Label>Color</Label>
        <Input />
      </div>
    )
  }
}

export default App
```

Box Component 를 준비합니다. Box 는 넓이, 높이, 색상을 Prop 로 받아 스타일을 구성합니다.

```javascript
const Box = styled.div`
  ${({ width, height, color }) => 
    width && height && color && css`
    width: ${width}px;
    height: ${height}px;
    background-color: ${color};
  `}
`
```

이번에는 Box 에게 넘겨줄 State 를 추가합니다.\
그리고 추가된 State 를 Box 에게 넘겨줍니다.&#x20;

```javascript
// App.js

import React from 'react'
import styled, { css } from 'styled-components'

const Label = styled.h2`
  color: #333;
`

const Input = styled.input`
  padding: 10px 20px;
`

const Button = styled.button`
  display: block;
  background: #03A9F4;
  border: none;
  color: #fff;
  font-weight: bold;
  border-radius: 4px;
  padding: 5px 10px;
  margin-top: 20px;
`

const Box = styled.div`
  ${({ width, height, color }) => 
    width && height && color && css`
    width: ${width}px;
    height: ${height}px;
    background-color: ${color};
  `}
`

class App extends React.Component {
  state = {
    width: 0,
    height: 0,
    color: ''
  }

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

    return (
      <div>
        <Label>Width</Label>
        <Input />
        <Label>Height</Label>
        <Input />
        <Label>Color</Label>
        <Input />
        <Box width={width} height={height} color={color} />
      </div>
    )
  }
}

export default App
```

우리가 원하는 것은 Input 에 값을 입력하고 Input 에 맞는 State 가 변경이되면서 변경된 값이 Box 에게 전달되기를 원합니다.

Input 의 onChange Event 를 추가하여 바뀌는 값을 캐치해보겠습니다.

```javascript
// App.js

import React from 'react'
import styled, { css } from 'styled-components'

const Label = styled.h2`
  color: #333;
`

const Input = styled.input`
  padding: 10px 20px;
`

const Box = styled.div`
  ${({ width, height, color }) => 
    width && height && color && css`
    width: ${width}px;
    height: ${height}px;
    background-color: ${color};
  `}
`

class App extends React.Component {
  state = {
    width: 0,
    height: 0,
    color: ''
  }

  handleStyles = (e) => {
    console.log(e.target)
  }

  render () {
    const { state: { width, height, color }, handleStyles } = this 

    return (
      <div>
        <Label>Width</Label>
        <Input name="width" onChange={handleStyles}/>
        <Label>Height</Label>
        <Input name="height" onChange={handleStyles} />
        <Label>Color</Label>
        <Input name="color" onChange={handleStyles} />
        <Box width={width} height={height} color={color} />
      </div>
    )
  }
}

export default App
```

![](/files/-Lo5_EbMgctHbbRwWtUM)

각 Input 들은 onChange 를 통해 handleStyles 함수를 호출합니다. handleStyles 함수는 event 객체를 넘겨받습니다.\
event 객체에는 해당 이벤트에 대한 정보를 담고있습니다.\
Input 들은 name 값을 가지고 있고 Input 이기 때문에 value attribute 를 가지고 있습니다.\
우리는 이 값들을 이용하여 state 를 변경하려고합니다.

JSX 에서 Event 를 걸어줄때는 함수를 JSX 내부가 아닌 class 아래쪽으로 빼주는 것이 좋습니다.&#x20;

handleStyles 함수에 넘어오는 event 객체를 통해 Input 의 name 과 value 를 가져옵니다.

```javascript
// App.js

handleStyles = ({ target: { name, value }}) => {
  console.log(name, value)
}
```

![](/files/-Lo5_YwQ1fdHvhplgFjd)

이제 이 값들을 이용해서 State 의 정보를 update 합니다.\
State 를 update 할 때는 반드시 setState 라는 함수를 이용해야합니다.

기존의 State 들은 유지하면서 새로 들어온 key, value 값만 update 합니다.

```javascript
// App.js

handleStyles = ({ target: { name, value }}) => {
  this.setState({ ...this.state, [name]: value })
}
```

### Hook 을 이용하기&#x20;

hook 은 위에서 알아본 Class Component 와는 살짝 다릅니다.\
State 선언과 update는  useState 라는 것을 이용합니다.

```javascript
// App.js

import React, { useState } from 'react'
import styled, { css } from 'styled-components'

const Label = styled.h2`
  color: #333;
`

const Input = styled.input`
  padding: 10px 20px;
`

const Box = styled.div`
  ${({ width, height, color }) => 
    width && height && color && css`
    width: ${width}px;
    height: ${height}px;
    background-color: ${color};
  `}
`

function App () {
  const [styles, setStyles] = useState({
    width: 0,
    height: 0,
    color: ''
  })

  const handleStyles = ({ target: { name, value }}) => {
    setStyles({ ...styles, [name]: value })
  }

  const { width, height, color } = styles 

  return (
    <div>
      <Label>Width</Label>
      <Input name="width" onChange={handleStyles}/>
      <Label>Height</Label>
      <Input name="height" onChange={handleStyles} />
      <Label>Color</Label>
      <Input name="color" onChange={handleStyles} />
      <Box width={width} height={height} color={color} />
    </div>
  )
}

export default App
```


---

# 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/06.-event.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.
