본문 바로가기
Front-End/React

[ React ] React 기본 ② React에서 DOM 조작하기

by 2CHAE._.EUN 2022. 9. 28.

저장 버튼을 클릭했을 때 작성자와 일기가 정상적으로 입력되었는지 확인하고 아니라면 focus 하기

 

1. 버튼을 클릭했을 때 발생하는 이벤트 핸들러 함수에 각 state에 대한 조건문을 사용해서 길이에 제한을 두면 된다.

 

DairyEditor.js

 const handleSubmit = () => {
        
       if(state.author.length < 1){
        alert("작성자를 최소 1글자 이상 입력해주세요");
        return ;
       }

       if(state.content.length < 1){
        alert("본문 내용을 최소 1글자 이상 입력해주세요");
        return ;
       }

        alert("저장 성공");
    }

 

alert를 갑자기 띄어버리는 것은 좋지 않다. → alert 대신 input 태그와 textarea에 focus를 주는 방식을 사용한다.

 

2.  input 태그와 textarea에 focus를 주는 방법

 

focus를 주기 위해서는 리액트에서 제공하는 DOM 요소를 선택할 수 있는 기능을 사용해야한다. useRef 

 

 

import { useRef } from "react";

const authorInput = useRef();

 

useRef()의 반환 값을 authorInput에 담아준다. 그러면 authorInput에는 React.MutableRefObject가 저장이 된다.

MutableRefObject은 HTML DOM 요소에 접근할 수 있는 기능을 한다. 

 

<input ref={authorInput} name="author" value={state.author} onChange={handleChangeState}></input>

 

input 태그에 ref 객체를 전달해주면 authorInput라는 레퍼런스 객체를 통해 input 태그에 접근할 수 있게 된다.

 

const authorInput = useRef();

    const handleSubmit = () => {

       if(state.author.length < 1){
        authorInput.current.focus();
        return ;
       }

       if(state.content.length < 1){
        alert("본문 내용을 최소 1글자 이상 입력해주세요");
        return ;
       }

        alert("저장 성공");
    }

 

authorInput.current.focus();

 

DOM 요소를 선택하는 useRef라는 기능으로 생성한 래퍼런스 객체는 현재 가리키는 값을 current 프로퍼티로 불러와서

사용을 할 수 있다. 즉 authorInput.current는 author에 대한 Input 태그가 되고 그 태그에 focus 기능을 사용할 수 있다.

 

import { useRef, useState} from "react";

const DiaryEditor = () => {

    const [state, setState] = useState({
        author : "",
        content : "",
        emotion : 1
    });

    const handleChangeState = (e) => {
        setState({
            ...state,
            [e.target.name] : e.target.value
        })
    }
    
    const authorInput = useRef();
    const contentInput = useRef();

    const handleSubmit = () => {

       if(state.author.length < 1){
        authorInput.current.focus();
        return ;
       }

       if(state.content.length < 1){
        contentInput.current.focus();
        return ;
       }

        alert("저장 성공");
    }

    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        <div>
            <input ref={authorInput} name="author" value={state.author} onChange={handleChangeState}></input>
        </div>
        <div>
            <textarea ref={contentInput} name="content" value={state.content} onChange={handleChangeState}></textarea>
        </div>
        <div>
            <select name="emotion" value={state.emotion} onChange={handleChangeState}>
                <option value={1}>1</option>
                <option value={2}>2</option>
                <option value={3}>3</option>
                <option value={4}>4</option>
                <option value={5}>5</option>
            </select>
        </div>
        <div>
            <button onClick={handleSubmit}>일기 저장하기</button>
        </div>
    </div>;
};

export default DiaryEditor;