리액트 제어 컴포넌트와 비제어 컴포넌트

웅평·2023년 8월 3일
0

제어 컴포넌트

  • input의 value 값을 리액에서 지정
  • 리액에서 사용하는 값과 input 값이 항상 일치
import { useState } from "react";

function Mycomponent() {
    const [values, setValues] = useState('');

    const handleChange = (e) => {
        const nextValues = e.target;
        setValues(nextValues);
    };

    return <input value={values} onChange={handleChange} />
    }
    
    function App() {
      return (
          <div>
              <Mycomponent />
          </div>
      );
	}

export default App;

const nextValues = e.target.toUperCase(); 로 바꾸면 소문자 입력해도 input 값이 대문자로 나온다

비제어 컴포넌트

  • input의 value 값을 리액트에서 지정하지 않음
  • 파일 input은 비제어 로 만들어야 한다
import { useState } from "react";

function Mycomponent() {
    const [values, setValues] = useState('');

    const handleChange = (e) => {
        const nextValues = e.target.toUperCase();
        setValues(nextValues);
    };

    return <input onChange={handleChange} />
    }
    
    function App() {
      return (
          <div>
              <Mycomponent />
          </div>
      );
	}

export default App;

input 값이 소문자로 입력되지만 리액트 개발자 도구에서 State 값을 확인하면 대문자로 나온다

파일 input

  • 이벤트 객체의 target.files를 통해서 가져올 수 있다
  • 콘솔에 파일리스트가 출력되는데 파일은 여러 개 선택할 수 있으니까 유사 배열 형태이다
  • 파일 input은 비제어 input 이다
  • 파일input의 value 속성은 사용자만 바꿀 수 있고 자바스크립트로 바꿀 떄는 빈 문자열로만 바꿀 수 있다
import { useEffect, useRef } from "react";

// 이미지 파일 선택 창
function FileInput() {
	const [value, setValue] = useState();
    const handleChange = (e) => {
        const nextValue = e.target.files[0];
        setValue(nextValue);
    };
  
    return <input type="file" onChange={handleChange} />;
}
  
export default FileInput;

ref로 DOM 노드 가져오기

Ref 객체 생성

import { useRef } from 'react';

// ...

const ref = useRef();

ref Prop 사용하기

const ref = useRef();

// ...

<div ref={ref}> ... </div>

Ref 객체에서 DOM 노드 참조하기

const node = ref.current;
if (node) {
  // node 를 사용하는 코드
}
  • Ref 객체의 current 라는 프로퍼티를 사용하면 DOM 노드를 참조할 수 있다
import { useEffect, useRef } from "react";

// 이미지 파일 선택 창
function FileInput({ name, value, onChange }) {
    const inputRef = useRef();

    const handleChange = (e) => {
        const nextValue = e.target.files[0];
        onChange(name, nextValue);
    };

    useEffect(() => {
        if (inputRef.current) {
            console.log(inputRef);
        }
    }, []);
  
    return <input type="file" onChange={handleChange} ref={inputRef}/>;
}
  
export default FileInput;
  

DOM 노드는 반드시 랜더링이 끝나야 생기니까 ref 객체의 current 값도 화면에 검포넌트가 랜더링 됐을 때만 존재한다 그래서 항상 값이 존재하는지 inputRef.current를 통해서 확인한다

참고
코드잇

0개의 댓글