useRef
: useRef는 리액트 훅의 한 종류로, Ref는 reference(참조)의 줄임말이다.
- useRef를 이용하면 특정한 DOM요소에 접근이 가능하면, 불필요한 재렌더링을 하지 않는다는 장점이 있다.
const 변수명 = useRef(초기값)
useRef는 변수명에 초기값을 적는 식으로 만든다.
이러한 결과값으로, {current: 초기값} 을 지닌 객체가 반환된다.
useRef에서 기억할 것은 이러한 current라는 키값을 지닌 프로퍼티가 생성되고, 값에 어떤 변경을 줄때도 이 current를 이용해서 한다는 점이다.
<input ref= {변수명}/>
그리고 이렇게 반환할 수 있다.
useRef() 를 사용 할 때 파라미터를 넣어주면, 이 값이 .current 값의 기본값이 된다.
그리고 이 값을 수정 할때에는 .current 값을 수정하면 되고 조회 할 때에는 .current 를 조회하면 된다.
useRef를 쓰는 이유는 반환된 useRef 객체는 컴포넌트의 전생애주기를 통해 유지가 된다.
(= 컴포넌트가 계속해서 렌더링이 되어도 컴포넌트가 언마운드되기 전까지는 값을 그대로 유지할 수 있다)
(= currnet 속성은 값을 변경해도 상태를 변경할 때 처럼 React 컴포넌트가 재렌더링 되지 않는다. )
-> 자주 변경되는 값을 state에 담으면, 변경될때마다 재렌더링이 일어나서 성능에 안좋은 영향을 미친다.
하지만 useRef를 이용하면 값이 변경될때마다 렌더링이 일어나지 않는다.
map
: 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환하는 함수이다.
- 어떠한 배열을 랜더링 하기 위해서는 코드를 그대로 작성해도 되지만 그러면 별로 효율적이지가 않다. 그래서 map 함수를 사용한다.
arr.map(function(currentValue[, index[, array]]) {
// 변환(mapping)할 로직: 변환된 결과를 반환해야 합니다.
}[, thisArg]);
(* arr: 함수에 적용할 배열이다.)
function | arr 배열의 각 요소에 적용할 때 호출되는 콜백 함수입니다. 이 함수는 세 개의 매개변수를 가질 수 있습니다.
|
thisArg | 옵션. function을 실행할 때 this로 사용할 객체. 이 매개변수는 필요에 따라 사용됩니다. |
key 의 중요성
const array = ['a', 'b', 'c', 'd'];
이러한 배열이 있다고 가정하자.
array.map(item => <div>{item}</div>);
위 배열을 이렇게 랜더링 하자.
위 배열의 b 와 c 사이에 z 를 삽입하게 된다면, 리렌더링을 하게 될 때 <div>b</div> 와 <div>c</div> 사이에 새 div 태그를 삽입을 하게 되는 것이 아니라, 기존의 c 가 z 로바뀌고, d 는 c 로 바뀌고, 맨 마지막에 d 가 새로 삽입된다.
그 다음에 a 를 제거하게 된다면, 기존의 a 가 b 로 바뀌고, b 는 z 로 바뀌고, z는 c로 바뀌고, c는 d 로바뀌고, 맨 마지막에 있는 d 가 제거된다.
array.map(item => <div key={item.id}>{item.text}</div>);
하지만 이렇게 키값을 객체로 하고 이렇게 업데이트 될 때는 배열이 업데이트 될 떄 key 가 없을 때 처럼 비효율적으로 업데이트 하는 것이 아니라, 수정되지 않는 기존의 값은 그대로 두고 원하는 곳에 내용을 삽입하거나 삭제한다.
spread 연산자
: ES6부터는 배열을 합칠 때 spread 또는 전개 연산자라고 불리는 ... 기호가 많이 사용되는데 배열을 나타내는 [] 기호 안에서 어떤 원소 앞에 ... 기호를 붙이면 그 배열 내의 원소가 마치 펼쳐진 것처럼 해당 배열에 추가된다.
const numbers = [1, 2, 3];
const letters = ["A", "B"];
const spread = [...numbers, ...letters];
console.log(spread); // [1, 2, 3, 'A', 'B']
concat()메서드
: 연결하다(concatenate)를 의미하는 배열의 concat() 메서드를 사용하면 하나의 배열에 다른 배열을 합칠 수 있다.
const numbers = [1, 2, 3];
const letters = ["A", "B"];
const concatenated = numbers.concat(letters);
console.log(concatenated); // [1, 2, 3, 'A', 'B']
onRemove()함수
: 우선 이 함수는 id가 ~인 함수를 삭제시키는 기능을 가지고있다.
어떠한 값을 지우라는 이벤트가 발생하면
<UserList users={users} onRemove={onRemove} />
이렇게 지우면 된다.
참고로 onClick={onRemove(id)} 이런 식으로 코드를 작성하면 절대 안 된다. 이렇게 하면 컴포넌트가 렌더링 될 때 바로 모든 객체들이 삭제될 것입니다. 렌더링 됨과 동시에 onRemove() 함수를 실행하기 때문이다.
그래서 보통 onClick = {onRemove}으로 지정해서 ()를 제외하는 방법으로 함수가 즉시 실행되지 않게 하고, 클릭했을 때 실행이 되도록 해준다.
배열 항목 수정하기
- User 컴포넌트에 계정명을 클릭했을때 색상이 초록으로 바뀌고, 다시 누르면 검정색으로 바뀌도록 구현한다.
1. App 컴포넌트의 users 배열 안의 객체 안에 active 라는 속성을 추가한다.
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
});
};
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]);
const nextId = useRef(4);
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
};
setUsers(users.concat(user));
setInputs({
username: '',
email: ''
});
nextId.current += 1;
};
const onRemove = id => {
// user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
// = user.id 가 id 인 것을 제거함
setUsers(users.filter(user => user.id !== id));
};
return (
<>
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
</>
);
}
export default App;
2. User 컴포넌트에서 방금 넣어준 active 값에 따라 폰트의 색상을 바꿔주도록 구현한다.
import React from 'react';
function User({ user, onRemove }) {
return (
<div>
<b
style={{
cursor: 'pointer',
color: user.active ? 'green' : 'black'
}}
>
{user.username}
</b>
<span>({user.email})</span>
<button onClick={() => onRemove(user.id)}>삭제</button>
</div>
);
}
function UserList({ users, onRemove }) {
return (
<div>
{users.map(user => (
<User user={user} key={user.id} onRemove={onRemove} />
))}
</div>
);
}
export default UserList;
3. onToggle 이라는 함수를 구현한다.
배열의 불변성을 유지하면서 배열을 업데이트 할 때에도 map 함수를 사용 할 수 있다.
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
});
};
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]);
const nextId = useRef(4);
const onCreate = () => {
const user = {
id: nextId.current,
username,
email
};
setUsers(users.concat(user));
setInputs({
username: '',
email: ''
});
nextId.current += 1;
};
const onRemove = id => {
// user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
// = user.id 가 id 인 것을 제거함
setUsers(users.filter(user => user.id !== id));
};
const onToggle = id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
};
return (
<>
<CreateUser
username={username}
email={email}
onChange={onChange}
onCreate={onCreate}
/>
<UserList users={users} onRemove={onRemove} onToggle={onToggle} />
</>
);
}
export default App;
useEffect
: useEffect 함수는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook 이다.
- useEffect는 component가 mount(처음 나타났을 때) 됐을 때, component가 unmount(사라질 때) 됐을 때, component가 update(특정 props가 바뀔 때) 됐을 때, 특정 작업을 처리할 수 있다.
<기본 형태>
useEffect( function, deps )
- function : 수행하고자 하는 작업
- deps : 배열 형태이며, 배열 안에는 검사하고자 하는 특정 값 or 빈 배열
1. Component가 mount 됐을 때 (처음 나타났을 때)
- 컴포넌트가 화면에 가장 처음 렌더링 될 때 한 번만 실행하고 싶을 때는 deps 위치에 빈 배열을 넣는다.
useEffect(() => {
console.log('렌더링 될 때 마다 실행된다');
});
- 만약 배열을 생략한다면 리렌더링 될 때 마다 실행된다.
2. Component가 update 될 때 (특정 props, state가 바뀔 때)
- 특정값이 업데이트 될 때 실행하고 싶을 때는 deps 위치의 배열 안에 검사하고 싶은 값을 넣어준다.
(의존값이 들어있는 배열 deps 이라고도 한다. dependency를 의미.)
const mounted = useRef(false);
useEffect(() => {
if(!mounted.current){
mounted.current = true;
} else {
//ajax
}
},[바뀌는 값]);
3. Component가 unmount 될 때(사라질 때) & update 되기 직전에
- cleanup 함수 반환 (return 뒤에 나오는 함수이며 useEffect에 대한 뒷정리 함수라고 한다.)
- 언마운트 될 때만 cleanup 함수를 실행하고 싶을 때
: 두 번째 파라미터로 빈 배열을 넣는다.
- 특정값이 업데이트 되기 직전에 cleanup 함수를 실행하고 싶을 때
: deps 배열 안에 검사하고 싶은 값을 넣어준다.
'WINK-(Web & App) > React.js 스터디' 카테고리의 다른 글
[2024 여름방학 React.js 스터디] 이정욱 #4주차 react 하기 힘들어요 (0) | 2024.08.02 |
---|---|
[2024 여름방학 React.js 스터디] 이가인 #4주차 (0) | 2024.08.02 |
[2024 여름방학 React.js 스터디] 강보경 #4주차 (0) | 2024.08.02 |
[2024 여름방학 React.js 스터디] 김태일 #4주차 "리액트 입문(2)" (1) | 2024.08.02 |
[2024 여름방학 React.js 스터디] 김민서 #4주차 (0) | 2024.08.02 |