본문 바로가기
공부한것/React

[React] 간단한 사용자 입력 form 만들기 (useRef)

by flyda 2022. 7. 26.

react

1. label태그의 htmlFor

 label 태그와 input요소를 사용해서 사용자 입력 폼을 만드는데, htmlFor이 나왔다. 잘 이해가 가지 않아서 공식문서를 살펴보니 다음과 같이 한 줄 나와있고 끝이었다. 

htmlFor: for는 JavaScript에서 예약어이므로 React 엘리먼트는 htmlFor를 대신 사용한다. 

label 요소에서 왜 for을 사용하는 거지.??!!!  처음에는 반복문인가..? 했는데 찾아보니 역시 다른 거였다. 

간단한 label요소에 대한 설명은 다음 글을 참고했다.  (1-1. HTML <label> Taglabel for란?, 1-2 class와 for 속성 )

 

1-1. js에서 label for 사용법!  

label요소의 for에는 input의 id와 같은 값을 넣어줘야한다. 

<label for="student">Student</label>
<input type="radio" name="Occupation" id="student" value="student" />

만약 for을 쓰는 것이 귀찮다면 다음과 같이 label 태그로 input을 감싸주면 된다! 

<label for="student">
    Student
    <input type="radio" name="Occupation" id="student" value="student" />
</label>

 

1-2. React에서 label 사용법!!  

이것을 리액트에서 쓴다면 진짜 htmlFor인 것을 제외하면 같다.!! 

<div>
    <label htmlFor="image">Meetup Image</label>
    <input type="url" required id="image" ref={imageInputRef} /> 
</div>
<div>
  <input type=“radio” name={this.props.name} id={this.props.id} />
  <label htmlFor={this.props.id}>
      {this.props.label}
  </label>
</div>

 

 

2. ref사용하기 

 

2-1. ref의 개념

ref는 인강을 보고 이해가 잘 가지 않아서 추가로 잘 정리된 유튜브 강의를 참고했다. (1. React Hooks에 취한다 - useRef 완벽 정리 1# 변수 관리 | 리액트 훅스 시리즈, 2. )

ref는 컴포넌트에 접근할 수 있는 특수한 어트리뷰트이다. 

는 2가지가 있다. 

const ref = useRef(value)로 사용한다. ref는 {current:value} 형태이다! 

2-1-1. ref가 유용한 경우

1) 저장공간

  • state를 사용하는경우
  • ref에 값을 저장하는 경우 
    • ref의 변화(ref의 속의 값 변경) 컴포넌트 다시 렌더링 X 변수들의 값이 유지됨 
    • state의 변화 → 컴포넌트 다시 렌더링 → 그래도 ref의 값은 유지됨. 
    • 변경되지 말아야 할 값들을 저장하는데 유용함. 

2) DOM 요소에 접근 

  • 예를 들어 input요소를 클릭하지 않아도 focus()를 주고 싶을 때 많이 사용된다. js의 document.qureySelector() 같다!!

 

2-2. ref의 사용하기! 

이번 프로젝트에서는 ref를 돔 요소에 접근하기 위해서 사용하였다!  사용한 코드를 간단하게 살펴보면 다음과 같다!! 

import { useRef } from 'react'

import classes from "./NewMeetupForm.module.css";
import Card from "../ui/Card";

function NewMeetupForm() {
  // DOM 엘리먼트나 클래스 컴포넌트의 인스턴스에 접근하기 위해 ref 어트리뷰트를 함수 컴포넌트에서 사용하는 것은 됨. 
  //titleInputRef은 ref 어트리뷰트를 통해서 전달되기 위해서 이곳에 정의되어야함 
  const titleInputRef = useRef();  

  function submitHandler(event) {
    event.preventDefault();

    const enteredTitle = titleInputRef.current.value; //ref는 current에 값이 저장되어 있다! 


    const meetupData = {
      title: enteredTitle,
    }
    console.log(meetupData)
  }
 
  return <Card>
    <form className={classes.form} onSubmit={submitHandler}>
      <div className={classes.control}>
        <label htmlFor="title">Meetup Title</label>
        <input type="text" required id="title" ref={titleInputRef} />
      </div> 
      <div className={classes.actions}>
        <button>Add Meetup</button>
      </div>
    </form>
  </Card>
}

export default NewMeetupForm;

먼저 useRef를 react에서 불러온다.  useRef로 전달받을 변수를 선언하고, 전달하고 싶은 값을 가지고 있는 요소에 ref엘리먼트를 추가한다. ref로 전달받은 값은 current에 들어있다!!  titleInputRef.current.value로 값을 불러온다! 값을 불러올 수 있지만, 변경하지 않아야 한다!! 

 

3. 전체 코드! 

import { useRef } from 'react'

import classes from "./NewMeetupForm.module.css";
import Card from "../ui/Card";

function NewMeetupForm() {
  // DOM 엘리먼트나 클래스 컴포넌트의 인스턴스에 접근하기 위해 ref 어트리뷰트를 함수 컴포넌트에서 사용하는 것은 됨. 
  //titleInputRef은 ref 어트리뷰트를 통해서 전달되기 위해서 이곳에 정의되어야함 
  const titleInputRef = useRef();
  const imageInputRef = useRef();
  const addressInputRef = useRef();
  const discriptionInputRef = useRef();
  function submitHandler(event) {
    event.preventDefault();

    const enteredTitle = titleInputRef.current.value;
    const enteredImage = imageInputRef.current.value;
    const enteredAddress = addressInputRef.current.value;
    const enteredDiscription = discriptionInputRef.current.value;

    const meetupData = {
      title: enteredTitle,
      image: enteredImage,
      address: enteredAddress,
      discription: enteredDiscription
    }
    console.log(meetupData)
  }
 
  return <Card>
    <form className={classes.form} onSubmit={submitHandler}>
      <div className={classes.control}>
        <label htmlFor="title">Meetup Title</label>
        <input type="text" required id="title" ref={titleInputRef} /> 
      </div> 
      <div className={classes.control}>
        <label htmlFor="image">Meetup Image</label>
        <input type="url" required id="image" ref={imageInputRef} /> 
      </div>
      <div className={classes.control}>
        <label htmlFor="address">Address</label>
        <input type="text" required id="address" ref={addressInputRef}/> 
      </div>
      <div className={classes.control}>
        <label htmlFor="discription">Discription</label>
        <textarea required id="discription" rows='5' ref={discriptionInputRef} ></textarea>
      </div>
      <div className={classes.actions}>
        <button>Add Meetup</button>
      </div>
    </form>
  </Card>
}

export default NewMeetupForm;

 

 

 

리액트로 파일 업로드하기 참고

댓글