React/React 정리

React 문법 정리 3 - useRef , 배열 렌더링 및 추가 삭제 수정

2023. 4. 7. 09:18
목차
  1. useRef로 특정 DOM 선택하기
  2. 배열 렌더링하기
  3. useRef 로 컴포넌트 안의 변수 만들기
  4. 배열에 항목 추가하기
  5. 배열 항목 삭제하기
  6. 배열 항목 수정하기

https://react.vlpt.us/basic/10-useRef.html

 

10. useRef 로 특정 DOM 선택하기 · GitBook

10. useRef 로 특정 DOM 선택하기 JavaScript 를 사용 할 때에는, 우리가 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다. 리액트를 사용하는

react.vlpt.us

 

 

useRef로 특정 DOM 선택하기

 

리액트에서 DOM을 선택할 때 ref 라는 것을 사용한다.

React에서 state로만 해결할 수 없고, DOM을 반드시 직접 건드려야 할 때 사용하게 된다.

ex ) 특정 input에 focus 주기, 스크롤 박스 조작, Canvas 요소에 그림 그리기 등..

함수형 컴포넌트에서 ref를 사용할 때는 useRef라는 Hook 함수를 사용한다.

useRef는 리렌더링 하지 않는다. 컴포넌트의 속성만 조회&수정한다.

 

앞서 작성했던 Input 글에서 초기화 버튼을 눌렀을 때

이름 input에 포커스가 잡히도록 useRef를 사용해서 기능을 구현해보자

 

App.js

import React from "react";
import InputSample from "./InputSample";

function App() {
  return <InputSample />;
}

export default App;

 

InputSample.js

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

function InputSample() {
  const [inputs, setInputs] = useState({
    name: " ",
    nickname: " ",
  });

  const nameInput = useRef(); // Ref 객체 생성

  const { name, nickname } = inputs;

  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  const onReset = () => {
    setInputs({
      name: "",
      nickname: "",
    });
    nameInput.current.focus(); //
  };
  return (
    <div>
      <input
        name='name'
        placeholder='이름'
        onChange={onChange}
        value={name}
        ref={nameInput} //
      />
      <input
        name='nickname'
        placeholder='닉네임'
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

 

 

 

배열 렌더링하기

 

// map 함수

let arr = [3, 4, 5, 6];

let modifiedArr = arr.map(function(element){
    return element *3;
});

console.log(modifiedArr); // [9, 12, 15, 18]

 

배열이 고정적이면 상관없지만, 배열의 인덱스를 하나하나 조회해가면서 렌더링하는 방법은

동적인 배열을 렌더링하지 못한다.

동적인 배열을 렌더링 할 때는 js 배열의 내장함수 map()을 사용한다.

map() 함수는 배열 안에 있는 각 원소를 변환하여 새로운 배열을 만들어준다.

리액트에서 동적 배열을 렌더링해야 할 때는 이 함수를 이용해

일반 데이터 배열을 리액트 엘리먼트로 이루어진 배열로 변환해주면 된다.

 

App.js

import React from "react";
import UserList from "./UserList";

function App() {
  return <UserList />;
}

export default App;

 

UserList.js

import React from "react";

function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}

function UserList() {
  const users = [
    {
      id: 1,
      username: "daramG",
      email: "daramG@daram.com",
    },
    {
      id: 2,
      username: "pinkbean",
      email: "pinkbean@daram.com",
    },
    {
      id: 3,
      username: "raichu",
      email: "raichu@daram.com",
    },
  ];
  // user = {user}
  // 앞의 user : User 컴포넌트에 들어가는 user 인자
  // 뒤의 {user} : users 배열의 각 원소값
  // +
  // 배열 안의 원소가 가지고 있는 고유한 값이 없다면 key = {index}
  // 각 고유 원소에 key가 있어야만 배열이 업데이트 될 때 효율적으로 렌더링된다.
  return (
    <div>
      {users.map((user) => (
        <User user={user} key={user.id} />
      ))}
    </div>
  );
}

export default UserList;

 

↓  (배열을 App 에서 선언하고 UserList에게 props로 전달하는 코드로 변경)

 

App.js

import React from "react";
import UserList from "./UserList";

function App() {
  const users = [
    {
      id: 1,
      username: "daramG",
      email: "daramG@daram.com",
    },
    {
      id: 2,
      username: "pinkbean",
      email: "pinkbean@daram.com",
    },
    {
      id: 3,
      username: "raichu",
      email: "raichu@daram.com",
    },
  ];
  return <UserList users={users} />;
}

export default App;

 

UserList.js

import React from "react";

function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}

function UserList({ users }) {
  return (
    <div>
      {users.map((user) => (
        <User user={user} key={user.id} />
      ))}
    </div>
  );
}

export default UserList;

 

 

실행결과 )

 

 

useRef 로 컴포넌트 안의 변수 만들기

 

// useRef()는 언제 사용하는가

https://yoonjong-park.tistory.com/entry/React-useRef-%EB%8A%94-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80

 

 

useRef Hook은 DOM을 선택하는 것 외에도, 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리할 수도 있다.

useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않는다.

다음과 같은 값을 관리할 수 있다.

- setTimeout, setInterval 을 통해 만들어진 id

- 외부 라이브러리를 사용해 생성된 인스턴스

- scroll 위치

 

 

App에 useRef()를 사용하여 nextId 라는 변수 생성

 

App.js

import React, { useRef } from "react";
import UserList from "./UserList";

function App() {
  const users = [
    {
      id: 1,
      username: "daramG",
      email: "daramG@daram.com",
    },
    {
      id: 2,
      username: "pinkbean",
      email: "pinkbean@daram.com",
    },
    {
      id: 3,
      username: "raichu",
      email: "raichu@daram.com",
    },
  ];

  // useRef() 파라타미터로 다음 id가 될 숫자 4를 넣어준다.
  // 파라미터 값을 넣어주면 해당 값이 변수의 current 값이 된다.
  // nextId 변수를 수정하거나 조회려면 .current 값을 수정하거나 조회한다.
  const nextId = useRef(4);
  const onCreate = () => {
    // 배열 항목 추가, 나중에 구현
  }

  return <UserList users={users} />;
}

export default App;

 

 

 

배열에 항목 추가하기

 

App.js

import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;

  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value, // name 키를 가진 값을 value로 변경
    });
  };

  const [users, setUsers] = useState([
    {
      id: 1,
      username: "daramG",
      email: "daramG@daram.com",
    },
    {
      id: 2,
      username: "pinkbean",
      email: "pinkbean@daram.com",
    },
    {
      id: 3,
      username: "raichu",
      email: "raichu@daram.com",
    },
  ]);

  // useRef() 파라타미터로 다음 id가 될 숫자 4를 넣어준다.
  // 파라미터 값을 넣어주면 해당 값이 변수의 current 값이 된다.
  // nextId 변수를 수정하거나 조회려면 .current 값을 수정하거나 조회한다.
  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    // 불변성을 지키면서 배열에 새 항목 추가 : spread 연산자 사용
    setUsers([...users, user]);
    //또는 아래와 같이 concat 함수 사용해 새로운 원소가 추가된 새로운 배열 생성
    // setUsers(users.concat(user));

    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1;
  };

  return (
    <div>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} />
    </div>
  );
}

export default App;

 

CreateUser.js

import React from "react";

function CreateUser({ username, email, onChange, onCreate }) {
  return (
    <div>
      <input
        name='username'
        placeholder='계정명'
        onChange={onChange}
        value={username}
      ></input>
      <input
        name='email'
        placeholder='이메일'
        onChange={onChange}
        value={email}
      ></input>
      <button onClick={onCreate}>등록</button>
    </div>
  );
}

export default CreateUser;

 

UserList.js

import React from "react";

function User({ user }) {
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
    </div>
  );
}

function UserList({ users }) {
  return (
    <div>
      {users.map((user) => (
        <User user={user} key={user.id} />
      ))}
    </div>
  );
}

export default UserList;

 

 

실행결과 )

 

배열 항목 삭제하기

 

App.js

해당 코드 추가 작성

 

UserList.js

해당 코드 추가 작성

 

 

실행결과 )

 

 

배열 항목 수정하기

 

User 컴포넌트에 계정명 클릭했을 때 색상 초록색으로 바뀌고 다시 누르면 검정색으로 바뀌도록 구현

 

App.js

import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;

  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value, // name 키를 가진 값을 value로 변경
    });
  };

  const [users, setUsers] = useState([
    {
      id: 1,
      username: "daramG",
      email: "daramG@daram.com",
      active: true,
    },
    {
      id: 2,
      username: "pinkbean",
      email: "pinkbean@daram.com",
      active: false,
    },
    {
      id: 3,
      username: "raichu",
      email: "raichu@daram.com",
      active: false,
    },
  ]);

  const nextId = useRef(4);
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };

    setUsers([...users, user]);

    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1;
  };

  // UserList.js에서 onRemove(user.id)
  const onRemove = (id) => {
    // user.id가 파라미터로 일치하지 않는 원소 추출해서 새로운 배열 생성
    // user.id가 id인 것을 제거
    setUsers(
      users.filter((user) => {
        return user.id !== id;
      })
    );
  };

  const onToggle = (id) => {
    // id 값 비교해 id가 다르면 그대로, 같아면 active값 토글
    setUsers(
      users.map((user) =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  };

  return (
    <div>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
    </div>
  );
}

export default App;

 

UserList.js

import React from "react";

function User({ user, onRemove, onToggle }) {
  // cursor : "pointer"
  // cursor 필드 사용해 마우스 올렸을 때 커서가 손가락 모양으로 변하게 설정
  return (
    <div>
      <b
        style={{
          cursor: "pointer",
          color: user.active ? "green" : "black",
        }}
        onClick={() => onToggle(user.id)}
      >
        {user.username}
      </b>{" "}
      <span>({user.email})</span>
      <button onClick={() => onRemove(user.id)}>삭제</button>
    </div>
  );
}

function UserList({ users, onRemove, onToggle }) {
  return (
    <div>
      {users.map((user) => (
        <User
          user={user}
          key={user.id}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      ))}
    </div>
  );
}

export default UserList;

 

실행화면 ) 

'React > React 정리' 카테고리의 다른 글

React 문법 정리 2 - useState, input 상태관리, 불변성  (0) 2023.04.06
React 문법 정리 1 - 값 전달, 조건부 렌더링  (0) 2023.03.30
  1. useRef로 특정 DOM 선택하기
  2. 배열 렌더링하기
  3. useRef 로 컴포넌트 안의 변수 만들기
  4. 배열에 항목 추가하기
  5. 배열 항목 삭제하기
  6. 배열 항목 수정하기
'React/React 정리' 카테고리의 다른 글
  • React 문법 정리 2 - useState, input 상태관리, 불변성
  • React 문법 정리 1 - 값 전달, 조건부 렌더링
daramG
daramG
dotori Java
daramG
다람쥐의 개발 블로그
daramG
전체
오늘
어제
  • 분류 전체보기 (193)
    • Java 코딩테스트 공부 (67)
      • Java 알고리즘 공부 (37)
      • Java 백준 문제풀이 (27)
      • Java 코테 나만의 팁 (3)
    • SQL Study (0)
      • Programmers SQL 문제풀이 (0)
      • SQLP 준비 (0)
    • 웹 개발 지식 정리 (0)
      • Servlet (0)
      • Java 정리 (0)
    • 자바 스프링 (45)
      • 스프링 공부 (4)
      • 스프링 게시판 프로젝트 (6)
      • 부트 블로그 JPA 프로젝트 (30)
      • react & springboot (5)
      • 스프링 오류창고 (0)
      • 리액트 + 스프링 프로젝트 (0)
      • pf (0)
      • pfError (0)
    • React (6)
      • React 정리 (3)
      • React 오류 창고 (3)
    • C++ 코딩테스트 공부 (중단) (20)
      • c++ 백준 문제풀이 (15)
      • c++ 알고리즘 공부 (5)
    • Unity (3)
      • Unity 공부 (3)
    • WebRTC (2)
      • WebRTC 강의학습 정리 (0)
      • WebRTC 프로젝트 (1)
    • 김영한님의 스프링 강의 학습 (10)
      • 스프링 강의 목차 (1)
      • 인텔리제이 & 스프링 기초 (1)
      • 스프링 핵심 원리 (8)
    • 전공 지식 정리 (40)
      • interview (0)
      • Java (0)
      • 운영체제 (4)
      • 데이터베이스 설계 (10)
      • 소프트웨어 공학 (3)
      • 유닉스 (14)
      • 디지털 논리회로 (0)
      • 인공지능 (7)
      • js (0)
      • etc (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • React&Spring 강의수강
  • 무서운 이야기
  • Java 백준 문제풀이
  • Unity 공부
  • 김영한의 스프링 핵심 원리
  • 스프링 프로젝트
  • 유닉스
  • 인공지능
  • 스프링부트 프로젝트
  • Java 코테 나만의 팁
  • 스프링 공부
  • 코테 알고리즘
  • 부트 jpa 게시판 프로젝트
  • 스프링부트 블로그 프로젝트
  • 백준 c++
  • java
  • 김영한 스프링 강의
  • java 알고리즘
  • 디지털 논리회로
  • 운영체제
  • 노마드코더의 zoom클론코딩
  • 데이터베이스 설계
  • C++ 알고리즘
  • 김영한 스프링 입문

최근 댓글

최근 글

hELLO · Designed By 정상우.
daramG
React 문법 정리 3 - useRef , 배열 렌더링 및 추가 삭제 수정
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.