본문 바로가기

공부기록/[강의노트] Udemy React 완벽가이드 101~200

# 114 [udemy React 완벽 가이드 노트] ref 사용해보기

 

ref의 기본적인 특성과 기능


 

 

다른 DOM요소에 접근해 그것들로 작업하게 해줌

useRef는 함수형 컴포넌트에서만 사용 가능 

 

 

우리는 

useState로 사용자가 작성한 내용들을 저장해 관리하고 있음 

그러나 사용자가 작성한 모든 내용을 관리하는 건 좀 과해보임 

 

마지막 렌더링되는 HTML 요소들과 다른 자바스크립트 코드의 연결

 

목표 : ref를 input태그와 연결해보기 


1. import 해주기 

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

 

2. 변수에 저장하기

ref는 요소에 연결하여 해당 요소와 작업할 수 있게 특정 값을 반환함.

  const nameInputRef = useRef();
  const ageInputRef = useRef();

 

default값은 필요 없음 

ref와 연결하려는 엘리먼트로 가서 ref 속성을 추가해줌 (모든 HTML요소에 가능)

지금은 input엘리먼트

 

<input
	id="username"
	type="text"
	onChange={nameChangeHandler}
	value={enteredName}
	ref={nameInputRef}></input>
    
    
    ...
    
    
<input
	id="userAge"
	type="number"
	onChange={ageChangeHandler}
	value={enteredAge}
	ref={ageInputRef}></input>

이렇게 되면  nameInputRef에 저장되어있던 값이

실제 DOM요소가 된다.

 

ref값은 객체임.

그 객체는 current프롭을 갖는데 

ref가 연결된 곳의  실제 값을 가진다.

실제  DOM노드를 가진다. 

이걸 조작하는건 추천하지 않음 

그냥 읽기만 사용하자.

 

 

enteredName과 enteredUserAge를 적당한 곳에 넣어주자. 

그러면 userState를 삭제해도 잘 동작한다. 

 

 

 

 

import classes from "./userInput.module.css";
import React, { useState, useRef } from "react";
import Card from "../UI/Card";
import Button from "../UI/Button";
import ErrorModal from "../UI/ErrorModal";

const UserInput = props => {
  const nameInputRef = useRef();
  const ageInputRef = useRef();
  // const [enteredName, setEnteredName] = useState("");
  // const [enteredAge, setEnteredAge] = useState("");
  const [error, setError] = useState();

  // const nameChangeHandler = e => {
  //   setEnteredName(e.target.value);
  // };

  // const ageChangeHandler = e => {
  //   setEnteredAge(e.target.value);
  // };

  const submitHandler = e => {
    e.preventDefault();
    const enteredUserName = nameInputRef.current.value;
    const enteredUserAge = ageInputRef.current.value;

    if (
      enteredUserName.trim().length === 0 ||
      enteredUserAge.trim().length === 0
    ) {
      setError({
        title: "Invalid input",
        message: "Please enter a valid name and age (non-empty values).",
      });
      return;
    }
    if (+enteredUserAge < 1) {
      setError({
        title: "Invalid age",
        message: "Please enter a valid age (> 0)",
      });
      return;
    }

    const userData = {
      id: Math.random().toString(),
      name: enteredUserName,
      age: enteredUserAge,
    };
    props.onSaveUserData(userData);
    // setEnteredName("");
    // setEnteredAge("");
  };

  // if (enteredName.trim().length === 0 || enteredAge.trim().length === 0) {
  //   setError({
  //     title: "Invalid input",
  //     message: "Please enter a valid name and age (non-empty values).",
  //   });
  //   return;
  // }
  // if (+enteredAge < 1) {
  //   setError({
  //     title: "Invalid age",
  //     message: "Please enter a valid age (> 0)",
  //   });
  //   return;
  // }
  //   const userData = {
  //     id: Math.random().toString(),
  //     name: enteredName,
  //     age: enteredAge,
  //   };
  //   props.onSaveUserData(userData);
  //   setEnteredName("");
  //   setEnteredAge("");
  // };

  const errorHandler = () => {
    setError(null);
  };
  return (
    <>
      {error && (
        <ErrorModal
          title={error.title}
          message={error.message}
          onConfirm={errorHandler}
        />
      )}
      <Card className={classes.input}>
        <form onSubmit={submitHandler}>
          <div>
            <label htmlFor="username">Username</label>
            <input
              id="username"
              type="text"
              value={nameInputRef}
              // onChange={nameChangeHandler}
              // value={enteredName}
            ></input>
          </div>
          <div>
            <label htmlFor="userAge">Age(Years)</label>
            <input
              id="userAge"
              type="number"
              value={ageInputRef}
              // onChange={ageChangeHandler}
              // value={enteredAge}
            ></input>
          </div>
          <div>
            <Button type="submit">Add User</Button>
          </div>
        </form>
      </Card>
    </>
  );
};

export default UserInput;

 

ref값 빈 값으로 재설정해주기


form 태그의 onSubmit={submitHandler} 속성으로 실행된 곳에

nameInputRef.current.value = "";
ageInputRef.current.value = "";

 

라고 해준다. 

 

 

 const submitHandler = e => {
    e.preventDefault();
    const enteredUserName = nameInputRef.current.value;
    const enteredUserAge = ageInputRef.current.value;

    if (
      enteredUserName.trim().length === 0 ||
      enteredUserAge.trim().length === 0
    ) {
      setError({
        title: "Invalid input",
        message: "Please enter a valid name and age (non-empty values).",
      });
      return;
    }
    if (+enteredUserAge < 1) {
      setError({
        title: "Invalid age",
        message: "Please enter a valid age (> 0)",
      });
      return;
    }

    const userData = {
      id: Math.random().toString(),
      name: enteredUserName,
      age: enteredUserAge,
    };
    props.onSaveUserData(userData);
    nameInputRef.current.value = "";
    ageInputRef.current.value = "";
    // setEnteredName("");
    // setEnteredAge("");
  };

그러면 form을 제출한 후에는 input에 빈값이 설정된다.