Input창을 클릭하면 해당 값을 수정할 수 있고, 다른 영역을 눌렀을 때에는 변경된 내용으로 값이 저장되는 기능으로 이해했습니다.
그렇기 때문에 input의 값을 저장하는 state와 focus가 벗어났을 때 저장될 state를 따로 관리했습니다.
nameInputValue, ageInputValue
state를 업데이트하고,onfocus
이벤트 핸들링으로 focus되었을 때에는 input의 text가 전체 선택되도록 하고, onblur
이벤트 핸들링으로 focus되지 않았을 때에는 임시로 저장한 inputValue
을 각각의 nameResult, ageResult
state로 업데이트 했습니다.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
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