Make Be BackEnd
useRef, useNavigate, useLocation, useRecoilState, useEffect, React.FC 본문
useRef, useNavigate, useLocation, useRecoilState, useEffect, React.FC
Initsave 2024. 7. 29. 21:01useRef
특정 DOM요소에 직접적으로 접근을 할 수 있다. 일반적으로 리액트는 직접적인 접근을 허용하지 않는다. (리액트는 상태(state)와 속성(props)을 통해 UI를 업데이트하고 관리한다.)
DOM요소에 접근 하는 이유 ?
- 특정 DOM요소에 접근
- 직접적인 DOM조작이 필요한 경우
- 비제어 컴포넌트(Uncontrolled Components)
const 변수 = useRef<HTMLInputElement>(null);
/*
DOM 객체주소가 필요한 상황이 생기는 경우 , useRef를 사용한다.
HTMLInputElement, 표준 HTML 입력 요소를 나타내고, TypeScript의 타입 시스템을 통해 타입 검사를 제공
title 의 값을 null로 초기화 하는 이유는 초기화 시점의 DOM요소가 없기(처음 랜더링 될 때는 해당 요소가 없다) 때문이다.
> 초기화의 필요성
1. DOM 요소가 아직 존재하지 않음
2. 타입 안전성
3. 랜더링 후 업데이트
useRef를 사용한 경우 '.current'를 통해 ref의 객체의 값을 얻을 수 있다.
*/
!title.current?.value || query.push(`searchTitle=${title.current?.value}`);
/*
1. title.current?.value
title은 useRef를 통해 생성된 참조 객체입니다.
title.current는 현재 참조하는 DOM 요소를 가리킵니다.
예를 들어, <input> 요소를 참조하고 있다면, title.current는 해당 input 요소입니다.
title.current?.value는 선택적 체이닝(옵셔널 체이닝) 연산자를 사용하여
title.current가 존재하는 경우 그 요소의 value 속성에 접근합니다.
만약 title.current가 null 또는 undefined일 경우,
title.current?.value는 undefined가 됩니다.
2. !title.current?.value
! 연산자는 논리 부정을 의미합니다. title.current?.value가 undefined, null,
빈 문자열("") 또는 false일 경우, 이 표현식은 true로 평가됩니다.
따라서, title.current?.value가 존재하지 않거나 빈 값일 때
!title.current?.value는 true가 됩니다.
3. || query.push(...)
|| 연산자는 논리 OR 연산자입니다. 왼쪽 표현식이 false일 경우, 오른쪽 표현식을 평가합니다.
이 코드에서 !title.current?.value가 true일 경우, query.push(...)가 실행됩니다.
즉, title.current?.value가 존재하지 않거나 빈 값일 때, query 배열에
새로운 쿼리 문자열이 추가됩니다.
전체 작동 방식
이 코드의 목적은 title.current?.value가 비어 있거나 존재하지 않을 때,
쿼리 배열(query)에 searchTitle 파라미터를 추가하는 것입니다.
만약 title.current?.value가 존재하고 비어 있지 않다면, 쿼리 배열에 추가되지 않습니다.
*/
useNavigate
React Router v6에서 제공, 훅은 프로그래밍 방식으로 페이지를 탐색하는 데 사용된다. 이전 버전 React Router에서는 ‘useHistory’를 사용하여 동일하게 작동했다 하지만 v6에서는 ‘useNavigate’로 대체
useNavigate 훅을 사용하면 함수형 컴포넌트 내에서 프로그래밍 방식으로 다른 경로로 이동할 수 있다. 주로 버튼 클릭이나 폼 제출과 같은 이벤트 핸들러 내에서 사용된다.
import React from 'react';
import { useNavigate } from 'react-router-dom';
const HomePage = () => {
const navigate = useNavigate();
const handleButtonClick = () => {
navigate('/about');
};
return (
<div>
<h1>Home Page</h1>
<button onClick={handleButtonClick}>Go to About Page</button>
</div>
);
};
export default HomePage;
여러가지 사용법
- 특정 경로로 이동
- navigate('/path');
- 경로와 상태 함께 전달
- navigate('/path', { state: { from: 'home' } });
- 경로 변경 후 다시 탐색 방지
- navigate('/path', { replace: true });
- 한 단계 앞으로 이동
- navigate(1);
- 한 단계 뒤로 이동
- navigate(-1);
/* 로그인 폼에서 'useNavigate'를 사용해서 로그인 성공 후 대시보드로 이동하는 예제 */
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
const LoginForm = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// 여기서 실제 로그인 로직을 수행합니다.
if (username === 'user' && password === 'password') {
navigate('/dashboard');
} else {
alert('Invalid credentials');
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</label>
</div>
<div>
<label>
Password:
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</label>
</div>
<button type="submit">Login</button>
</form>
);
};
export default LoginForm;
useLocation
현재의 URL 경로, 쿼리 파라미터 및 해시를 포함한 위치 객체를 반환, useLocation을 사용하면 현재 페이지의 경로에 대한 정보를 쉽게 접근하고, 이를 기반으로 컴포넌트를 랜더링하거나 로직을 처리할 수 있다.
- pathname: 현재 URL의 경로 부분 (예: /home, /products) , 현재 URL 경로
- search: URL의 쿼리 문자열 부분 (예: ?query=react), 쿼리 문자열
- hash: URL의 해시 부분 (예: #section1), 해시
- state: Link 컴포넌트에서 전달된 상태 (있다면), 상태 (있다면)
기본 사용법
import React from 'react';
import { useLocation } from 'react-router-dom';
const LocationDisplay = () => {
const location = useLocation();
return (
<div>
<p><strong>Current Path:</strong> {location.pathname}</p>
<p><strong>Query String:</strong> {location.search}</p>
<p><strong>Hash:</strong> {location.hash}</p>
<p><strong>State:</strong> {JSON.stringify(location.state)}</p>
</div>
);
};
export default LocationDisplay;
쿼리 문자열 처리
import React from 'react';
import { useLocation } from 'react-router-dom';
const QueryDisplay = () => {
const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const searchTerm = queryParams.get('searchTerm');
return (
<div>
<p><strong>Search Term:</strong> {searchTerm}</p>
</div>
);
};
export default QueryDisplay;
리디렉션과 조건부 렌더링
import React from 'react';
import { useLocation } from 'react-router-dom';
const ConditionalRender = () => {
const location = useLocation();
return (
<div>
{location.pathname === '/special-page' && <p>Special page content</p>}
</div>
);
};
export default ConditionalRender;
export interface 로 타입을 지정하는 이유는?
TypeScript가 정적 타입 검사를 통해 코드의 안정성과 오류를 줄이기 위해서 이다.
- 타입 안정성: 타입을 지정함으로써 코드에서 발생할 수 있는 오류를 사전에 방지합니다.
- 자동 완성 및 문서화: IDE에서 자동 완성 기능과 문서화 기능을 통해 개발 생산성을 향상시킵니다.
- 가독성 및 유지보수성: 명확한 타입 정의로 코드의 가독성을 높이고 유지보수를 쉽게 합니다.
- 모듈화 및 재사용성: 공통의 타입 정의를 재사용하여 코드의 일관성을 유지합니다.
- 동적 타입 검사: 정적 타입 검사를 통해 런타임 오류를 줄이고 안정적인 코드를 작성합니다.
useRecoilState
컴포넌트 상태관리 라이브러리이고, Recoil의 상태를 읽고 업데이트하는 데 사용된다.
- Atom : Recoil 상태의 기본 단위, 상태 저장, 해당 상태를 읽거나 업데이트 하는 방법 제공
- /* 상태 정의 */ import { atom } from 'recoil'; export const exampleState = atom({ key: 'exampleState', // 고유한 키 default: '', // 기본 값 }); /* 컴포넌트에서 상태를 읽고 업데이트 */ import React from 'react'; import { useRecoilState } from 'recoil'; import { exampleState } from './atoms'; // atom 파일에서 가져오기 const ExampleComponent: React.FC = () => { const [value, setValue] = useRecoilState(exampleState); const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { setValue(event.target.value); // 상태 업데이트 }; return ( <div> <input type="text" value={value} onChange={handleChange} /> <p>Current Value: {value}</p> </div> ); }; export default ExampleComponent;
- Selector : Recoil 상태를 기반으로 파생된 상태 계산하는데 사용, 상태를 변형하거나 조합하여 새로운 값을 생성
‘useRecoilState’ 훅은 현재 상태, 상태를 업데이트하는 함수를 반환한다.
useRecoilState vs useRecoilValue vs useSetRecoilState
/* useRecoilValue */
import { useRecoilValue } from 'recoil';
import { exampleState } from './atoms';
const DisplayComponent: React.FC = () => {
const value = useRecoilValue(exampleState);
return (
<div>
<p>Current Value: {value}</p>
</div>
);
};
export default DisplayComponent;
/* useSetRecoilState */
import { useSetRecoilState } from 'recoil';
import { exampleState } from './atoms';
const UpdateComponent: React.FC = () => {
const setValue = useSetRecoilState(exampleState);
const handleClick = () => {
setValue('New Value'); // 상태 업데이트
};
return (
<button onClick={handleClick}>Update Value</button>
);
};
export default UpdateComponent;
useEffect
사이드 이펙트를 관리하기 위해 사용하는 훅, 사이드 이펙트란 컴포넌트의 렌더링과는 직접적으로 관련이 없는 작업을 의미, 예를 들어 데이터 fetching, 구독 설정, DOM 직접 조작 등이 사이드 이펙트에 해당된다.
/* 기본 사용 */
import React, { useState, useEffect } from 'react';
const ExampleComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
// 이 코드는 컴포넌트가 렌더링된 후 실행됩니다.
document.title = `Count: ${count}`;
// cleanup 함수는 컴포넌트가 언마운트되거나
// 의존성 배열의 값이 변경될 때 실행됩니다.
return () => {
document.title = 'React App';
};
}, [count]); // count가 변경될 때마다 Effect가 실행됩니다.
return (
Count: {count}
);
};
export default ExampleComponent;
/* 의존성 배열 */
// 빈배열
useEffect(() => {
console.log('Component mounted');
return () => {
console.log('Component unmounted');
};
}, []); // 빈 배열
// 특정 값
useEffect(() => {
console.log('Value changed:', dependency);
return () => {
console.log('Cleanup for value:', dependency);
};
}, [dependency]); // dependency 값이 변경될 때마다 Effect 실행
// 의존성 배열 생략
useEffect(() => {
console.log('Component rendered');
});
// Cleanup 함수
useEffect(() => {
const timer = setInterval(() => {
console.log('Timer tick');
}, 1000);
// Cleanup 함수
return () => {
clearInterval(timer);
};
}, []); // 빈 배열, 컴포넌트가 마운트 될 때만 타이머 설정
/* API에서 데이터 가져오는 예제 */
// 데이터 Fetching
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const DataFetchingComponent = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('<https://api.example.com/data>');
setData(response.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, []); // 빈 배열, 컴포넌트가 처음 렌더링될 때만 데이터 fetching
if (loading) return
Loading...
;
if (error) return
Error: {error.message}
;
return (
Data
- {data.map(item => (
- {item.name} ))}
);
};
export default DataFetchingComponent;
URLSearchParams란 ?
JavaScript의 내장 객체로 URL의 쿼리 문자열을 쉽게 조작하고 관리할 수 있도록 도와준다, 주로 URL의 쿼리 문자열을 파싱, 생성, 수정하는데 사용
React.FC
TypeScript와 React를 함께 사용할 때, 함수형 컴포넌트(Function Component)를 정의하기 위해 사용되는 타입이다. 이 타입을 사용하면 컴포넌트의 Props를 명확하게 정의하고 타입 안전성을 높일 수 있다.
기본적으로 ‘children’을 포함하는 Props를 제공한다. (java에서 인터페이스와 비슷하다)
/* 기본 사용법 */
import React, { FC } from 'react';
interface MyComponentProps {
title: string;
isActive: boolean;
}
const MyComponent: FC<MyComponentProps> = ({ title, isActive }) => {
return (
<div>
<h1>{title}</h1>
<p>{isActive ? 'Active' : 'Inactive'}</p>
</div>
);
};
export default MyComponent;
'React' 카테고리의 다른 글
| 클래스형 컴포넌트, 함수형 컴포넌트, 배열 컴포넌트 (0) | 2024.08.01 |
|---|---|
| React 생명주기 (0) | 2024.07.30 |
| 디바운스(debounce), 스로틀(throttle) (0) | 2024.07.29 |
| 리액트 클래스 컴포넌트에서는 컴포넌트의 생명 주기 (1) | 2024.07.29 |
| 라이브러리 사용 (0) | 2024.07.18 |