React input 요소에서 value 와 defaultValue의 차이

controlled Component vs uncontrolled Component

React에서 form을 작성할 때 2가지 주요 패턴을 사용한다

 

먼저 react의 state와 통합된 controlled Component

입력 요소를 react가 제어하고, 입력값을 상태로 유지한다

 

그리고 통합하지 않고, DOM에 의해 관리되는 uncontrolled Component 

useRef를 사용하여 DOM 요소의 값을 직접 접근하여 사용한다

 

controlled Component

기본값은 react를 통해 결정되며, input의 value에 state를 넣어주면 된다

그리고 변하는 값은 onChange에서 이벤트 핸들러를 통해 setState를 호출하여 항상 react 상태와 동기화된다

import React, { useState } from 'react';

function ControlledForm() {
    const [inputValue, setInputValue] = useState('');

    const handleChange = (e) => {
        setInputValue(e.target.value);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        alert(`Submitted value: ${inputValue}`);
    };

    return (
        <form onSubmit={handleSubmit}>
            <label>
                Input:
                <input type="text" value={inputValue} onChange={handleChange} />
            </label>
            <button type="submit">Submit</button>
        </form>
    );
}

export default ControlledForm;

 

 

uncontrolled component

기본값은 defaultValue 속성을 통해 설정된다

 

ref 값은 DOM 요소에 대한 참조값이 들어가는데, 컴포넌트가 마운트 된 후, ref에 연결된 DOM요소를 생성하고, 그 요소를 ref.current에 할당한다 

 

컴포넌트가 언마운트되면 해당 요소는 null이 된다

import React, { useRef } from 'react';

function UncontrolledForm() {
    const inputRef = useRef(null); // ref 객체 선언

    const handleSubmit = (e) => {
        e.preventDefault();
        alert(`Submitted value: ${inputRef.current.value}`);
    };

    return (
        <form onSubmit={handleSubmit}>
            <label>
                Input:
                <input type="text" ref={inputRef} /> // ref 전달
            </label>
            <button type="submit">Submit</button>
        </form>
    );
}

export default UncontrolledForm;

 

value 속성이 DOM값보다 우선시되므로 value를 사용하면 onChange에 핸들러를 걸어줘야 한다

핸들러 없이 value를 주었을 때

 

결론

controlled Component - value

uncontrolled Component - defaultValue

 

참고자료

 

Uncontrolled Components – React

A JavaScript library for building user interfaces

legacy.reactjs.org