getElenentById()
처럼, Component의 어떤 부분을 선택할 수 있게 해주는 방법이다.ref={변수명}
을 넣어주면, 해당 Component를 참조하게 된다.import React, {Component} fome 'react'
class RefSample extends Component {
state = {
height: 0
};
input = null;
box = null;
const handleClick = () => {
this.input.focus();
};
render() {
return (
<div>
<input ref={ref => {this.input = ref}} />
<button onClick={this.handleClick}> Focus Input </button>
<div ref={ref => {this.box = ref}}>
<h2>Title</h2>
<p>Content</p>
</div>
<p>
<b> height </b> {this.state.height}
</p>
</div>
)
}
}
export default RefSample;
ㅁ. 특정 DOM을 가리킬 때 사용하는 Hook함수 (focus설정, 특정element의 style변경 등..)
ㅁ. DOM에 접근(이렇게 쓸 경우는 많지않음)
ㅁ. 어떤 가변값을 유지하는데에 편리함
- DOM을 직접 선택해야하는 상황
- 특정요소의 값을 가져오기
- 스크롤바 위치
- 포커스설정
- const 사용자정의이름 = useRef(null)
- const 사용자정의이름 = useRef()
- const 사용자정의이름 = useRef(숫자)
> * <실제돔 ref={사용자정의이름}>
- 사용자정의이름.current
- 사용자정의이름.current.xxx명령어
- .current 프로퍼티에 변경가능한 값을 담고있는 "상자"
interface MutableRefObject<T> {
current: T;
}
interface RefObjext<T> {
readonly current: T | null;
}
const timeout = useRef(null); //RefObject 반환해서 current가 readonly가 됨
timeout.current = setTimeout(() => {
startTime.current = new Date().getTime();
}, Math.floor(Math.random() * 1000) + 2000);
// const timeout = useRef<number | null>(null);
// 이걸로 교체해줘야 오류가 안남
import React, {useRef} from 'react';
const App = () => {
//1.Ref객체 만들기
const here = useRef();
//2.focus() DOM API호출
setTimeout(() => here.current.focus(), 3000);
return (
<div>
<h1> Hello </h1>
//3.원하는 곳에 ref값으로 설정하기
<input
ref={here}
placeholder="how are you"
/>
</div>
);
}
export defaulg App;
* 1. useRef()를 사용해 Ref객체 만들기 : const here = useRef();
* 2. 해당 객체를 활용한 작업설정 : .current.focus()
* 3. 만든 Ref객체를 선택하고싶은 DOM에 ref값으로 설정하기 : ref={here}
=> Ref객체의 .current 값은 선택한 DOM을 가리키게 된다.
+) useRef에 파라미터를 넣어주면 이 값이 .current 의 기본값이 된다.
import React, {useState, useRef} from 'react';
import "./styles.css";
const App = () => {
const [name, setName] = useState('');
const [nickName, setNickName] = useState('');
const hereref = useRef(); //useRef객체생성
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeNickName = (e) => {
setNickName(e.target.value);
}
const onClickReset = () => {
setName('');
setNickName('');
// 버튼 클릭시 지정한 위치에 focus 되도록
hereref.current.focus();
}
rerurn (
<>
// 원하는 위치(DOM)에 ref값을 설정한다.
<input
value={name}
onChange={onChangeName}
hereref={ref} />
<input
value={nickName}
onchange={onChangeNickName} />
<button onClick={onClickReset}>
리셋버튼
</button>
<div>
<h3> 결과 </h3>
<h4>
{name}의 별명은 {nickName}입니다.
</h4>
</div>
</>
);
};
export default App;
useRef를 통해 관리되는 변수가 주로 쓰이는 곳
setTimeout
,setInterval
을 통해 만들어진id
- Scroll의 위치
- 배열에 새 항목이 추가 될 때 필요한 고유 key값
- 외부 라이브러리를 사용하여 생성된 인스턴스
import React, {useRef} from 'react';
import UserList from './UserList';
const App = () => {
const users = [ //1.현재 users 라는 배열에 3명의 user가 존재하기 때문에
{
id: 1,
name: 'hjeen'
},
{
id: 2,
name: 'ijun'
},
{
id: 3,
name: 'hjij'
}
];
const nextId = useRef(4); //2.다음에 추가되면 해당 user.id=4 이므로 이렇게 .current 의 기본값을 설정해준다.
const onCreate = () => {
// 배열에 항목추가 소스
nextId.current += 1; //3.그후 배열을 추가하는 부분에 새로 추가되는 배열의 id값을 이렇게 1씩 증가시킨다.
};
return (
<React.Fragment>
<UserList users={users} />
</React.Fragment>
);
};
export default App;
useEffect( () => {
mount 시 실행할 함수;
return () => {
unmount 시 실행할 내용
}
}, [deps값])
* 기본 사용법
1. 먼저 `mount` 시 실행할 함수를 작성한다.
2. 반환 값에는 `unmount`시 실행할 내용을 작성한다. (cleanUp)
3. `deps`값에 특정 값을 넣으면, 해당 값이 업데이트 될 때마다 useEffect에 작성한 함수가 재실행된다.
* `빈 배열`로라도 두어야 useEffect에 작성한 함수가 처음 mount 될 때만 실행 됨 (생략하면 리렌더링 될 때마다 계속 함수를 불러오게 됨)
* `cleanup`함수 : 해당 effect가 더이상 실행할 필요가 없을 때 청소하는 용도. 더이상 실행할 필요가 없는 경우(1),(2)
(1) dependancy(두번째 인자로 넘기는 배열)가 바뀌어서 effect가 달라져야 할 때 (이전 effect 청소)
(2) 해당 Component가 unmount 될 때
** deps 정리
*** 정리하자면, deps가 []일 떄,
1. 컴포넌트가 처음 나타날 때에만 useEffect에 등록한 함수가 호출 됨.
2. return 값은 컴포넌트가 사라질 때 호출 됨
*** deps에 특정 값을 넣으면 이럴 때 호출이 된다.
1. 컴포넌트가 처음 마운트 될 때 ( []일 때도 가능 )
2. 컴포넌트가 언마운트 될 때 ( []일 때도 가능 )
3. 지정한 값이 바뀌기 직전에
4. 지정한 값(deps에 넣은 값)이 바뀔 때
=> useEffect 안에서 사용하는 상태나 props가 있다면, deps에 넣어주어야 하는게 규칙이다. 그래야 useEffect 에 등록한 함수가 실행 될 때, 최신 props 나 상태를 가리키기 때문이다.
Component가 마운트/un마운트/업데이트 될 때, 할 작업을 선택하도록 하는 Hook함수
=> 기존의 class형에서는 세가지의 각 상태들을 따로 관리해야했는데 useEffect로 한번에 관리 가능
(외부 API를 요청하거나 반복작업/작업예약 등에 쓰인다)
* 세가지의 상태들을 기존의 메서드와 매칭하여 좀 더 알아보자,
1. `mount` : Component가 처음 화면에서 보여질 때 (새로고침시) (ComponentDidMount메서드)
2. `unmount` : Component가 화면에서 사라질 때 (ComponentWillUnmount메서드)
3. `update` : 특정 props가 바뀌어 Component가 업데이트 될 때 (ComponentWillUpdate메서드)
import React, {useEffect, useRef} from 'react';
const useClick = (onClick) => {
// 예외처리
if (typeof onClick !== 'function') {
return;
}
const element = useRef();
useEffect( () => {
// mount 시 실행 (click시, 받아 온 onClick함수 실행)
if (element.current) {
element.current.addEventListener('click', onClick);
}
return () => {
if (element.current) {
element.current.removeEventListener('click', onClcik);
}
};
}, []);
return element;
}
const App = () => {
const sayHello = () => {
console.log('Hello');
};
const title = useClick(sayHello); //useClick훅에 sayHello함수를 전달
return (
<div>
<h1 ref={title}>
Hello
</h1>
</div>
)
}