06. Event

๋“ค์–ด๊ฐ€๊ธฐ์ „

React ์—์„œ๋Š” ์ง์ ‘์ ์ธ DOM ์˜ ์ ‘๊ทผ๋ณด๋‹ค๋Š” State ๋ผ๋Š” ์ƒํƒœ ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ DOM ์— ๋ณ€ํ™”๋ฅผ ์ค€๋‹ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” Event ๋ฅผ ํ•™์Šตํ•˜์—ฌ State ๋ฅผ ๋‹ค์–‘ํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์Šต

ํ”„๋กœ์ ํŠธ๋Š” ์ดˆ๊ธฐ ์„ธํŒ… ์ƒํƒœ๋กœ ์ง„ํ–‰๋˜์–ด์ง‘๋‹ˆ๋‹ค. +@ ๋กœ ์ด์ œ๋Š” styled-component ๋ฅผ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— App.css ํŒŒ์ผ์ด ํ•„์š”์—†์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ž…๋ ฅํ•˜๋Š” ๊ฐ’์— ๋”ฐ๋ผ์„œ ๋„“์ด, ๋†’์ด, ์ƒ‰์ƒ์„ ๊ฐ€์ง„ ๋ฐ•์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

Input ์— ๊ฐ’์„ ์ž…๋ ฅํ•˜์—ฌ ์ž…๋ ฅ๋œ ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒ์ž๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋จผ์ € Input, Label Component ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

// 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 ๋กœ ๋ฐ›์•„ ์Šคํƒ€์ผ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

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

์ด๋ฒˆ์—๋Š” Box ์—๊ฒŒ ๋„˜๊ฒจ์ค„ State ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ถ”๊ฐ€๋œ State ๋ฅผ Box ์—๊ฒŒ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

// 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 ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐ”๋€Œ๋Š” ๊ฐ’์„ ์บ์น˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

// 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

๊ฐ Input ๋“ค์€ onChange ๋ฅผ ํ†ตํ•ด handleStyles ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. handleStyles ํ•จ์ˆ˜๋Š” event ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ๋ฐ›์Šต๋‹ˆ๋‹ค. event ๊ฐ์ฒด์—๋Š” ํ•ด๋‹น ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ ์žˆ์Šต๋‹ˆ๋‹ค. Input ๋“ค์€ name ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  Input ์ด๊ธฐ ๋•Œ๋ฌธ์— value attribute ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ๊ฐ’๋“ค์„ ์ด์šฉํ•˜์—ฌ state ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

JSX ์—์„œ Event ๋ฅผ ๊ฑธ์–ด์ค„๋•Œ๋Š” ํ•จ์ˆ˜๋ฅผ JSX ๋‚ด๋ถ€๊ฐ€ ์•„๋‹Œ class ์•„๋ž˜์ชฝ์œผ๋กœ ๋นผ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

handleStyles ํ•จ์ˆ˜์— ๋„˜์–ด์˜ค๋Š” event ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด Input ์˜ name ๊ณผ value ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

// App.js

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

์ด์ œ ์ด ๊ฐ’๋“ค์„ ์ด์šฉํ•ด์„œ State ์˜ ์ •๋ณด๋ฅผ update ํ•ฉ๋‹ˆ๋‹ค. State ๋ฅผ update ํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ setState ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด์˜ State ๋“ค์€ ์œ ์ง€ํ•˜๋ฉด์„œ ์ƒˆ๋กœ ๋“ค์–ด์˜จ key, value ๊ฐ’๋งŒ update ํ•ฉ๋‹ˆ๋‹ค.

// App.js

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

Hook ์„ ์ด์šฉํ•˜๊ธฐ

hook ์€ ์œ„์—์„œ ์•Œ์•„๋ณธ Class Component ์™€๋Š” ์‚ด์ง ๋‹ค๋ฆ…๋‹ˆ๋‹ค. State ์„ ์–ธ๊ณผ update๋Š” useState ๋ผ๋Š” ๊ฒƒ์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

// 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

Last updated

Was this helpful?