React

[React] useRef 사용해서 input 값 비워지고 커서 깜빡거리게 구현

carrotdy 2022. 6. 19. 13:24

useRef 문법

const refContainer = useRef(initialValue);

 

useRef 특징

1. 리렌더링 하지 않는다.

2. 컴포넌트의 속성만 조회, 수정이 가능하다.

 

useRef 사용

1. No. 1씩 증가하도록 구현

초기값을 1로 설정해 변수 no에 저장해주고, onAdd에서 id값을 no.current++로 설정하여

숫자가 하나씩 증가하도록 해준다.

 

 

2. input 값이 비워지고, 커서 깜빡거리게 구현

setText('') input 값이 비워지도록 설정해주고, textRef 초기값을 null로 설정해주어

textRef.current.focus() input에 커서가 깜빡거리게 구현하였다.

Ref객체의 current값은 우리가 선택하고자 하는 DOM을 가르키고 포커싱 해주는 DOM API focus()를 호출한다.

 

    const no = useRef(1) 
    const textRef = useRef(null)

    const onAdd = () => {
        setData([
            ...data,
            {
                id: no.current++,
                text: text
            }
        ])
        setText('')  
        textRef.current.focus() 
    }

 

 

<전체코드1>

import React, { useState, useRef } from 'react';

const Test4 = () => {
    const [data, setData] = useState([])
    const [text, setText] = useState('')
    const no = useRef(1)  //고유번호 만들기
    const textRef = useRef(null)

    const changeInput = (e) => {
        setText(e.target.value)
    }

    const onAdd = () => {
        setData([
            ...data,
            {
                id: no.current++,
                text: text
            }
        ])
        setText('')  //추가 누르면 내용 삭제되고 공백처리
        textRef.current.focus()  //커서 깜빡거리게
    }
    return ( 
        <div>
            <input type="text" value={text} onChange={changeInput} ref={textRef}/>
            <button onClick={onAdd}>추가</button>
            <hr />
            <ul>
                {
                    data.map( item => <li key={item.id}>
                        {item.id}/{item.text}
                    </li>)
                }
            </ul>
        </div>
    );
};

export default Test4;

 

 

<전체코드2>

전체코드 1에서는 div를 사용했는데 전체코드 2에서는 div대신에 form 태그를 사용하였다.

(div는 의미없는 태그라 form태그를 사용하는게 좋음)

 

form태그의 submit때문에 주소창에 text와 addr이 들어가게된다.

submit특징을 막아주기 위해서  e.preventDefault() 를 사용하였고,

공백이 들어왔을때는 다음으로 넘어가지 못하도록 if( !text || !addr ) return 조건문을 입력해주었다.

 

 

import { toHaveErrorMessage } from '@testing-library/jest-dom/dist/matchers';
import React, { useRef, useState } from 'react';

const Test5 = () => {
    const no = useRef(1)
    const textRef = useRef(null)
    const [data, setData] = useState([])  //{id:1, text:'ddd', addr:'sdfsdf'}
    const [form, setForm] = useState({
        text: '', addr: ''
    })
    const {text, addr} = form
 
    const onAdd = (e) => {
        e.preventDefault()  //submit특징을 막아주는 역할
 
        if( !text || !addr ) return  //공백이 들어왔을때는 넘어가지 못하도록 막아줄 수 있음
        // if(text.length === 0 || addr.length === 0) {  
        //     return 
        // }

        setData([
            ...data,
            {
                id : no.current++, 
                text : text,
                addr : addr,
            }
        ])
        setForm({
            text: '',
            addr: '',
        })
        textRef.current.focus()
    }

    const changeInput = (e) => {
        const {value, name} = e.target
        setForm({
            ...form,
            [name] : value  //name값만 수정
        })
    }

    return ( 
        <div>
            <form onSubmit={onAdd}>
                <input type='text' value={text} name="text" onChange={changeInput} ref={textRef}/>
                <input type='text' value={addr} name="addr" onChange={changeInput}/>
                <button type='submit'>추가</button>
            </form> 
            <hr />
            <ul>
                {
                    data.map( item => <li key={item.id}>
                        {item.id} / {item.text} / {item.addr}
                    </li>)
                }
            </ul>
        </div>
    );
};

export default Test5;
반응형