React input창 클릭으로 저장

박은정·2022년 2월 10일
0

TIL

목록 보기
41/72
post-thumbnail
post-custom-banner

간단한 리뷰

Input창을 클릭하면 해당 값을 수정할 수 있고, 다른 영역을 눌렀을 때에는 변경된 내용으로 값이 저장되는 기능으로 이해했습니다.

그렇기 때문에 input의 값을 저장하는 state와 focus가 벗어났을 때 저장될 state를 따로 관리했습니다.

  1. input에 onChange 이벤트 헨들링으로 nameInputValue, ageInputValue state를 업데이트하고,
  2. onfocus 이벤트 핸들링으로 focus되었을 때에는 input의 text가 전체 선택되도록 하고,
  3. onblur 이벤트 핸들링으로 focus되지 않았을 때에는 임시로 저장한 inputValue을 각각의 nameResult, ageResult state로 업데이트 했습니다.

ClickToEdit.js 코드

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

import Title from '../components/Title'
import Form from '../components/ClickToEdit/Form'

const ClickToEdit = () => {
  const [nameInputValue, setNameInputValue] = useState('김코딩')
  const [ageInputValue, setAgeInputValue] = useState(20)
  const [nameResult, setNameResult] = useState(nameInputValue)
  const [ageResult, setAgeResult] = useState(ageInputValue)

  const formArray = [
    {
      id: 'name',
      label: '이름',
      inputValue: nameInputValue,
      onChange: event => setNameInputValue(event.target.value),
      onfocus: event => event.target.select(),
      onblur: () => setNameResult(nameInputValue),
    },
    {
      id: 'age',
      label: '나이',
      inputValue: ageInputValue,
      onChange: event => setAgeInputValue(event.target.value),
      onfocus: event => event.target.select(),
      onblur: () => setAgeResult(ageInputValue),
    },
  ]

  return (
    <WholeBox>
      <Title text='ClickToEdit' />
      {formArray.map((formItem, formIndex) => {
        return <Form formItem={formItem} key={formIndex} />
      })}
      <TextBox>
        <Text>이름 {nameResult}</Text>
        <Text>나이 {ageResult}</Text>
      </TextBox>
    </WholeBox>
  )
}

const WholeBox = styled.div`
  padding: 10px;
`

const TextBox = styled.div`
  text-align: center;
`

const Text = styled.span`
  &:first-child {
    margin-right: 10px;
  }
`

export default ClickToEdit

Form.js 코드

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

const Form = ({ formItem }) => {
  const { id, label, inputValue, onChange, onfocus, onblur } = formItem

  return (
    <FormBox>
      <Label htmlFor={id}>{label}</Label>
      <Input
        type='text'
        id={id}
        value={inputValue}
        onChange={onChange}
        onFocus={onfocus}
        onBlur={onblur}
      />
    </FormBox>
  )
}

const FormBox = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 300px;
  height: 100px;
  margin: 0 auto 50px auto;
`

const Label = styled.label``

const Input = styled.input`
  display: inline-block;
  width: 200px;
  height: 50px;
  border: 1px solid lightgray;
  text-align: center;
  padding: auto;
  &:focus {
    outline: 3px solid tomato;
  }
`

export default Form
profile
새로운 것을 도전하고 노력한다
post-custom-banner

0개의 댓글