[React] Dom 조작하기

이재훈·2023년 6월 7일
0

React

목록 보기
7/27

목표

React에서 DOM 조작하기

  • 일기 저장 버튼 클릭했을 때
  • 이름과 내용의 유효성 검사 후
  • 옳지 않다면 focus하기

코드는 직전에 게시글과 동일합니다.

일기 저장 버튼을 클릭했을 시 이름은 1글자 이상, 내용은 5글자 이상 체크하는 로직을 구현해보도록 하겠습니다.

DiaryEditor.js

import { useState } from 'react'

const DiaryEditor = () => {

    const [state, setState] = useState({
        name: '',
        content: '',
        hungry: 10,
    })

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

    const handleSubmit = () => {
        if (state.name.length < 1) {
            alert('이름은 최소 1글자 이상 입력해주세요');
            return;
        }

        if (state.content.length < 5) {
            alert('내용은 최소 5글자 이상 입력해주세요');
            return;
        }

        alert('저장 성공');
    }

    return (
        <div className="DiaryEditor">
            <h2>오늘의 먹방 일기</h2>
            <div>
                이름
                <input name="name" value={state.name} onChange={handleChangeState}/>
            </div>
            <div>
                내용
                <textarea name="content"value={state.content} onChange={handleChangeState}/>
            </div>
            <div>
                배고픔 정도
                <select name='hungry' value={state.hungry
                } onChange={handleChangeState}> 
                    <option value={10}>10</option>
                    <option value={20}>20</option>
                    <option value={30}>30</option>
                    <option value={40}>40</option>
                    <option value={50}>50</option>
                    <option value={60}>60</option>
                    <option value={70}>70</option>
                    <option value={80}>80</option>
                    <option value={90}>90</option>
                    <option value={100}>100</option>
                </select>
            </div>
            <div>
                <button onClick={handleSubmit}>일기 저장하기</button>
            </div>
        </div>
    );
};

export default DiaryEditor;

요즘 트렌드는 alert를 사용하지 않습니다. 사용자 입장에서 alert창을 끄고 또 작성하기 귀찮기 때문이죠. 그래서 이것을 focus로 변경해보도록 하겠습니다.
react에서 제공하는 기능인 useRef를 사용하겠습니다.

DiaryEditor.js

import { useRef, useState } from 'react'

const DiaryEditor = () => {

    const nameInput = useRef();

    const [state, setState] = useState({
        name: '',
        content: '',
        hungry: 10,
    })

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

    const handleSubmit = () => {
        if (state.name.length < 1) {
            alert('이름은 최소 1글자 이상 입력해주세요');
            nameInput.current.focus();
            return;
        }

        if (state.content.length < 5) {
            alert('내용은 최소 5글자 이상 입력해주세요');
            return;
        }

        alert('저장 성공');
    }

    return (
        <div className="DiaryEditor">
            <h2>오늘의 먹방 일기</h2>
            <div>
                이름
                <input ref={nameInput} name="name" value={state.name} onChange={handleChangeState}/>
            </div>
            <div>
                내용
                <textarea name="content"value={state.content} onChange={handleChangeState}/>
            </div>
            <div>
                배고픔 정도
                <select name='hungry' value={state.hungry
                } onChange={handleChangeState}> 
                    <option value={10}>10</option>
                    <option value={20}>20</option>
                    <option value={30}>30</option>
                    <option value={40}>40</option>
                    <option value={50}>50</option>
                    <option value={60}>60</option>
                    <option value={70}>70</option>
                    <option value={80}>80</option>
                    <option value={90}>90</option>
                    <option value={100}>100</option>
                </select>
            </div>
            <div>
                <button onClick={handleSubmit}>일기 저장하기</button>
            </div>
        </div>
    );
};

export default DiaryEditor;

react의 기능이기 때문에 useRef를 import를 해주고

const nameInput = useRef();

로 nameInput을 선언해줍니다. 여기서 useRef()의 리턴형은 React.MutableRefObject<undefined> 입니다.

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

이렇게 적용하게 되면 name의 글자수가 1 미만인 경우 name input태그에 focus가 자동으로 되게 됩니다.

textarea에도 동일하게 적용해 보도록 하겠습니다.

DiaryEditor.js

import { useRef, useState } from 'react'

const DiaryEditor = () => {

    const nameInput = useRef();
    const contentInput = useRef();

    const [state, setState] = useState({
        name: '',
        content: '',
        hungry: 10,
    })

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

    const handleSubmit = () => {
        if (state.name.length < 1) {
            nameInput.current.focus();
            return;
        }

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

        alert('저장 성공');
    }

    return (
        <div className="DiaryEditor">
            <h2>오늘의 먹방 일기</h2>
            <div>
                이름
                <input ref={nameInput} name="name" value={state.name} onChange={handleChangeState}/>
            </div>
            <div>
                내용
                <textarea ref={contentInput} name="content"value={state.content} onChange={handleChangeState}/>
            </div>
            <div>
                배고픔 정도
                <select name='hungry' value={state.hungry
                } onChange={handleChangeState}> 
                    <option value={10}>10</option>
                    <option value={20}>20</option>
                    <option value={30}>30</option>
                    <option value={40}>40</option>
                    <option value={50}>50</option>
                    <option value={60}>60</option>
                    <option value={70}>70</option>
                    <option value={80}>80</option>
                    <option value={90}>90</option>
                    <option value={100}>100</option>
                </select>
            </div>
            <div>
                <button onClick={handleSubmit}>일기 저장하기</button>
            </div>
        </div>
    );
};

export default DiaryEditor;

이렇게 useRef를 사용하여 Dom을 조작해보았습니다.


해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글