리액트의 내부 원리에 대해 관심을 가지고 강의 외적인 부분 또한 공식문서를 찾아보며 개념 공부를 능동적으로 했다.
fetch('[https://learn.codeit.kr/api/foods?limit=2&search=토마토](https://learn.codeit.kr/api/foods?limit=2&search=%ED%86%A0%EB%A7%88%ED%86%A0)');
검색어 받기
리퀘스트 보내기
리스폰스 적용하기
1. 검색어가 바뀌면 데이터를 통째로 바꿔준다(기존에 받은 데이터에 더해주는 것이 아닌)
const [search, setSearch] = useState('');
const handleSearchSubmit = (e) => {
e.preventDefault();
setSearch(e.target['search'].value);
};
<form onSubmit={handleSearchSubmit}>
<input name="search" />
<button type="submit">검색</button>
</form>
value
로 스테이트를 설정한다onChange
이벤트에 등록한다onChange
핸들러에서 setState(e.target.value);
등으로 스테이트와 입력값의 싱크를 맞춰준다e.preventDefault()
써야함.state
로 폼 구현하기 - input
태그의 name
속성을 활용 const [values, setValues] = useState({
title: "",
rating: 0,
content: "",
});
const handleChange = (e) =>{
const {name, value} = e.target;
setValues((prev)=>({
...prev,
[name]: value,
}));
}
<form onSubmit={handelSubmit}>
<input name="title" value={values.title} onChange={handleChange}/>}
</form>
const [value, setValue] = useState('');
const handleChange = (e) =>{
const nextValue = e.target.value.toUpperCase();
setValue(nextValue);
}
return <input value={value} onChange={handleChange} />
실제 인풋 value를 리액트에서 지정하지 않는 컴포넌트
function FileInput(){
const [value, setValue] = useState();
const handleChange = (e) =>{
console.log(e.target.files);
}
return <input type="file" />
}
...
function ReviewForm(){
..
return (
...
<FileInput />
...
);
}
const inputRef = useRef();
useEffect(()=>{
if(inputRef.current){
console.log(inputRef.current);
}
}, [])
return <input type="text" ref={inputRef} />
import { useRef } from 'react';
function FileInput({ name, value, onChange }) {
const inputRef = useRef();
const handleChange = (e) => {
const nextValue = e.target.files[0];
onChange(name, nextValue);
};
const handleClearClick = () => {
const inputNode = inputRef.current;
if (!inputNode) return;
inputNode.value = '';
onChange(name, null);
};
return (
<div>
<input type="file" onChange={handleChange} ref={inputRef} />
<button type="button" onClick={handleClearClick}>
X
</button>
</div>
);
}
export default FileInput;
import { useRef } from 'react';
function FileInput({ name, value, onChange }) {
const inputRef = useRef();
const [preview, setPreview] = useState("");
const handleChange = (e) => {
const nextValue = e.target.files[0];
onChange(name, nextValue);
};
const handleClearClick = () => {
const inputNode = inputRef.current;
if (!inputNode) return;
inputNode.value = '';
onChange(name, null);
};
useEffect(()=>{
if(!value) return;
const newPreview = URL.createObjectURL(value);
setPreview(newPreview);
}),[value];
return (
<div>
<img src={preview} alt="이미지 미리보기" />
<input type="file" onChange={handleChange} ref={inputRef} />
<button type="button" onClick={handleClearClick}>
X
</button>
</div>
);
}
export default FileInput;
컴포넌트 안에서 외부의 환경을 바꾸거나 하는 행위를 사이드 이펙트라고 부른다. 보통 useEffect훅에서 사이드 이펙트를 발생시킨다. 정확히 말하면 사이드 이펙트를 발생시키기 위해서 useEffect를 사용한다.
위의 이미지 미리보기 예제에서도 사이드 이펙트가 발생한다. 사용자가 이미지파일을 계속 바꾸면 메모리상에 오브젝트 url들이 계속 쌓이게 된다. 이렇게 메모리에 불필요하게 남아있는 것을 방지하려면 revokeObjectURL함수를 쓰면 된다.
useEffect(()=>{
if (!value) return;
const newPreview = URL.objectURL(value);
setPreview(newPreview);
return () => {
setPreview();
URL.revokeObjectURL(newPreview); //메모리 해제
} //useEffect의 리턴한 콜백함수는 이전 useEffect의 사이드 이펙트를 정리하기 위해 다음 useEffect가 호출될 때 가장 먼저호출된다.
}, [value]);
페이지 정보 변경
useEffect(() => {
document.title = title; // 페이지 데이터를 변경
}, [title]);
네트워크 요청
useEffect(() => {
fetch('https://example.com/data') // 외부로 네트워크 리퀘스트
.then((response) => response.json())
.then((body) => setData(body));
}, [])
데이터 저장
useEffect(() => {
localStorage.setItem('theme', theme); // 로컬 스토리지에 테마 정보를 저장
}, [theme]);
타이머
useEffect(() => {
const timerId = setInterval(() => {
setSecond((prevSecond) => prevSecond + 1);
}, 1000); // 1초마다 콜백 함수를 실행하는 타이머 시작
return () => {
clearInterval(timerId);
}
}, []);
영화 리뷰 글들을 모아놓은 사이트 기준으로 설명한다.
프로그래밍에서 훅이란, 내가 작성한 코드를 다른 프로그램에 연결시켜 그 값이나 기능을 사용하는 것이다.
useState를 예로 들면, state는 사실 컴포넌트 안에 있는 값이 아니라 리액트가 따로 관리하는 값이다. 그래서 리액트가 관리하는 스테이트에 연결해서 마치 변수처럼 값을 사용하는 기능을 제공하므로 useState는 훅인 것이다.
훅의 규칙
위와 같이 개발자 도구에서 스테이트 값을 보려고 하면 우리가 정한 이름이 아닌 state라고 나온다. 리액트 스테이트는 실행한 순서를 기억하여 값을 구분하기 때문에 순서는 항상 같게 만들어야 한다. 반복문이나 조건문을 사용하여 훅을 쓰면 이 순서가 바뀔 수 있는 가능성이 있기 때문에 안된다.
공식문서를 찾아보고 어려운 개념을 이해하려고 하다 보니, 오늘 오전에 배운 개념들을 조금 까먹은 것 같다. 앞으로 너무 많은 개념을 한 번에 다 알아가려고 하지 말고, 고민해보다가 시간이 오래 걸릴 것 같으면 아카이빙 해두고 여우가 될 때 다시 찾아보는 방식을 택해야겠다.