본문 바로가기

WINK-(Web & App)/React.js 스터디

[2025 1학기 React.js 스터디] 이가인 #4주차

반응형

1. useRef 로 특정 DOM 선택

2. 배열 렌더링

3. useRef로 컴포넌트 안에 변수 만들기

4. 배열에 항목 추가

5. 배열 항목 제거 

6. 배열 항목 수정

7. useEffect


 

useRef 로 특정 DOM 선택하는 방법 - !

- ref 사용 이유

1. DOM에 직접 접근 가능

2. useState와 달리 값이 변해도 컴포넌트가 리렌더링되지 않고 값 저장 가능함

3. 이전 값이나 상태를 저장해두고 싶을 때 유용함 

 

 

- useRef라는 Hook 함수 사용

React에서 DOM 요소나 값의 참조(reference) 를 저장하고 유지하기 위해 사용하는 Hook

 

기존 InputSample코드에서 초기화 버튼을 클릭했을 때 포커스가 초기화 버튼에 그대로 남아있음

이름 input 에 포커스가 잡히도록 useRef 를 사용하여 기능을 구현해보겠습니다

 

어떻게 사용하느냐 ??

1. useRef() 사용해서 Ref 객체 만들고

const nameInput = useRef();

2. 이 객체를 우리가 선택하고 싶은 DOM에 ref값으로 설정

ref={nameInput}
 const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  };

 

current : 원하는 DOM을 가리킴 

focus() : DOM API인데 호출함 -> input에 포커스를 하는 함수라고 생각 하깅

 

 


배열 랜더링 하기

이런 배열이 있습니다

1. 기본적, 비효율

아 중복 에바입니다,

2. 컴포넌트 하나 더 생성, props 사용하기 

User 컴포를 새로 만들고 user을 props로 정의해서 재사용해줍니다
return은 이런식으로 됩니다

 

3. 동적인 배열인 경우 (고정적이지 않은) ➡️ map() 사용, key 설정

 

- key : 각 원소들마다 가지고 있는 고유값

 

- 고유값이 없다면 ? 

index를 사용하기 , 기본적으로 index 값이 사용됨 

 

- key 쓰는 이유

각 고유 원소에 key가 있어야만 배열이 업데이트 될 때 효율적으로 렌더링 될 수 있기 때문 !!

 

key가 없다면 ?

원소 추가/수정/삭제 할때 그 원소가 새로 추가되는게 아니고 기존 자리는 가만히 있게되고 기존 원소가 추가되는 방식으로 비효율적으로 업데이트 된다.

key를 쓴다면 ? 

배열이 업데이트 될 때 수정되지 않는 기존의 값은 그대로 두고 원하는 곳에 내용을 삽입하거나 삭제됨

User 컴포는 똑같이하고 요렇게 써줍니다. 이때 user의 id가 고유값입니다!


useRef 로 배열 변수 관리하기 

useState와 달리 값이 변해도 컴포넌트가 리렌더링되지 않는다!! 그리고 설정 후 바로 조회 할 수 있다 !

App컴포에 배열을 선언하고, 새 항목을 추가했을 때 이 새 항목에서 사용 할 고유 id를 관리하고 싶은 상황 

nextId 변수 만들기

useRef(4) : 파라미터 값이 .current의 기본값이 된다 !

--> 초기값이 4라는 건, 이미 저 배열에서 id 1~3가 있기 때문입니다

수정/조회 할 때 .current 수정/조회 하면 되어요


배열에 항목 추가하기 

🌟배열의 불변성 ➡️ 상태관리 를 위해 지켜야함 !

  - >.push, splice, sort 는 원본 배열 자체를 변경함 

이러면 안좋은점 : 기존 상태가 바뀌어 버려서 

1. 디버깅이 어려워짐

2. 변경 추적이 어려워짐

이런 안좋은점이 잇다네요,,, 

 

 --> 따라서 !! 복사본을 만들어 작업해야한다 ! 또는 concat 사용 ,,

 

 

CreateUser컴포는 그냥 input 두 개와 button 하나만 있음 , input 값 및 함수들을 props로 받음 ,
배열 선언과 실질적 관리는 App.js에서 함

 

1. spread 연산자( ...) 사용

 

2.  concat 함수 사용 

 -> 새로운 배열 반환(합쳐짐!!!) , 기존 배열은 변하지 않음 !!

setUsers(users.concat(user));

 

  • users: 기존 사용자 목록 (배열)
  • user: 새로 만든 사용자 객체
  • concat(user): users 배열 뒤에 user를 붙여 새 배열을 만들어서 반환

요래댓어요

 

 


배열 항목 제거하기  

먼저, UserList.js (input말고 밑에 리스트들만 있는거) 에 삭제 버튼 랜더링

UserList.js

<button onClick={() => onRemove(user.id)}>삭제</button>

"버튼을 클릭하면 onRemove 함수에 user.id를 넣어서 실행해라" 라는 뜻 !!

➡️해당 사용자만 삭제하게 하는 로직 

 

화살표 함수로 감싼이유?

➡️onClick={onRemove(user.id) 이렇게 쓰면 렌더링 될때 바로 실행되버림 ㅜㅜ 그래서 클릭할 때만 실행되게 익명 함수 () 로 감싸야한다 !

App.js 의 onRemove 정말 간단하네여

내장함수인 filter 이용하기 !

 

🌟filter 함수란? 

배열.filter(조건 함수)
  • 배열의 요소들을 조건에 맞는 것만 골라 새 배열을 만들어줌
  • 기존 배열은 변하지 않음 ➡️아까 말한 불변성 이 생각나네요 
users.filter(user => user.id !== id)
  • users 배열 안의 사용자 중에서 user.id가 id인 것(같은 사용자 하나)을 제거한 후 새 배열을 반환 한다는 뜻 

삭제가 잘 됩니당

 

 


배열 항목 수정하기  

하기전에,, on/off 방식의 토글을 만든다고 한다면, onToggle이라는 함수명을 쓰는것이 좋고, 이는 active 속성을 필요로 하다는 점을 알고있으면 좋습니다

 

1. 원래 배열에 active 값 추가 

첫번째꺼는 켜두고싶엇나봅니다

 

2. active 값 ( boolean 값 ) 에 따라 폰트의 색상 바꾸기 

 -> 얘는 style만 수정하면 됩니다

UserList.js입니다 보시다시피 boolean 값이기때문에 삼항연산자를 사용합니당

 

3. onToggle 구현하기 

마찬가지로 삼항 연산자 사용

  • users.map(user => ...) 

 : map으로 새 배열 반환, 새로운 배열이 만들어져 setUsers()로 상태 업데이트

 

  • user.id === id ? { ...user, active: !user.active } : user

: user.id와 id가 같으면 그 사용자의 active 값을 반전시키고 ( 해당 객체를 복사한뒤, !으로 반전시킴

그렇지 않으면 해당 사용자를 그대로 반환

 

 

4. UserList.js 수정 

onToggle 받아서 User에게 전달, id 넣어서 호출
good

 

 

 


useEffect로 작업 처리 .. 

useEffect 

  • useEffect는 컴포넌트가 렌더링될 때마다 특정 작업을 수행할 수 있도록 해줍니다
    1. 컴포넌트가 화면에 나타날 때 실행되는 작업(마운트) -> props 관리, 외부 API 요청 , 라이브러리 사용 등 
    2. 컴포넌트가 화면에서 사라질 때 실행되는 작업(언마운트)

1. 

useEffect(() => {
    console.log('컴포넌트가 화면에 나타남'); //첫번째 콜백
    return () => {
      console.log('컴포넌트가 화면에서 사라짐'); //두번째 콜백 (클린업 함수)
    };
}, []); // 빈 배열

 

1. 첫 번째 콜백 (마운트될때)

 : 컴포넌트가 처음 렌더링 될 때 이 코드가 실행됨 

 

2. 두 번쨰 콜백 (언마운트 될 때 :  useEffect에서는 함수를 반환할수있다 -> 클린업함수)

 : 클린업 함수를 반환할 수 있다. 언마운트 될 때 실행된다. 

  -> 이 함수는 컴포넌트가 사라지기 정리 작업을 할 수 있도록 도와줌 (뒷정리)

 

3. 빈 배열 (deps에 아무것도 넣지 않음 )

 : 두 번째 인자인데, 이는 컴포가 처음 렌더링 될때 첫번째 콜백함수가 한 번만 실행됨.

 

➡️ 보통 이 두 번째 인자에서 deps 파라미터를 사용함 ! 

이게뭐냐면 ,, 바로 의존성 배열 이라는 뜻 입니다..

 ->  따라서 이 배열 파라미터의 값들은 변경될 때 마다 useEffect의 콜백함수가 실행됩니다

 

나타남3개, 사라짐3개가 출력되는건 알겟는데

마지막 나타남 3개는 왜 출력되지?

-> react의 Strict mode 때문이라네요//.

우왕

2.

useEffect(() => {
    console.log('user 값이 설정됨');
    console.log(user);
    return () => {
      console.log('user 가 바뀌기 전..');
      console.log(user);
    };
}, [user]);

 

1. 첫 번째 콜백 

 : user 값이 바뀔 때 마다 실행됨, 현재 user 값을 콘솔에 출력함 

 

2. 두 번쨰 콜백 

 : 클린업 함수 는 user 값 변경 전 실행됨, deps 에 있는 값이 변경될 때 마다! 이전 user값을 출력함

 

3. deps 값 넣기 

 : user 값이 바뀔 때마다 useEffect가 재실행됨 . "이전 user 값을 출력하고, 새로운 user 값은 첫 번째 콜백에서 출력"

 

3.

useEffect(() => {
    console.log(user);
});

 

1. 첫 번째 콜백 

 : useEffect가 실행될 때마다 호출됨

 

2. deps 생략 시 

 : 컴포넌트가 렌더링 될 때마다 useEffect가 실행 -> 매번 user값이 콘솔에 출력됨 

삭제햇을 시 모든 user값 출력

 

이 경우에는 상태가 변경될 때마다 값을 출력하는 디버깅 방법을 쓸 때 유용합니당

 

 

 

오랜만에 해서 그런가... 꽤걸렷네요.. 감사합니당 화이팅~!

 

반응형