사이트 : 노마드코더
강의 : ReactJS로 영화 웹 서비스 만들기
시각 : 2022.04.24
◆ 완료한 강의 :
Render 될 때 마다 모든 자료를 새로고침하지 않고
어떤 특정 요소를 딱 한번만 실행시키고 싶을 때 쓰는 함수.
- 첫 렌더링 시 어떤 것을 딱 한번만 실행시켜줌.
- dependency(2nd argument)의 변화를 감지, 1st argument를 딱 한번 실행
- deps에는 감지할 여러가지 조건이 들어갈 수 있음
useEffect(1st argument, [2nd argument]);
1st argument : 첫 렌더링 시에만 실행될 함수
2nd argument : 변화를 감지하면 실행하도록 조건을 걸을 함수 등등
(변화가 감지되면 실행해달라고 react에게 알려주는 것)
function App() {
const [keyword, setKeyword] = useState("");
const [counter, setValue] = useState(0);
const onClick = () => setValue((prev) => prev + 1);
// 클릭 시 이전 값(기본 값 0부터 시작)에 1을 더해줌. 그 값이 counter가 됨
const onChange = (event) => setKeyword(event.target.value);
// input 검색 창에 입력하면(변화가 생기면)
그 입력값이(event.target.value) keyword의 value가 됨
console.log("i run all the time");
// 새로고침시 마다 실행됨
useEffect(() => {
console.log("I run only once");
}, []);
// deps(2nd argument)가 비었으므로 첫 렌더링시 딱 한번만 실행됨
useEffect(() => {
if (keyword !== "" && keyword.length > 5) {
console.log("SEARCH FOR", keyword);
}
}, [keyword]);
//useEffect도 함수라서 안에 if절 쓸 수 있음.
1. deps인 [keyword]의 변화를 감지한다.
2. 검색창에 값이 ""가 아니며, 또한(&&) 5자 초과하면 그때 실행됨
return (
<div>
<input
value={keyword}
onChange={onChange}
type="text"
placeholder="Search Here..."
/>
<h1>{counter}</h1>
<button onClick={onClick}>click me</button>
</div>
);
}
어떤 Component가 destroy 될 때도 무언가를 실행시켜 주는 것
예를 들어, 'h1' 태그 하나를 보이게 했다가 안보이게 다시 했을 때,
소스코드를 보면 잠시 숨는게 아니라, 아예 '없어짐'.
그 없어지는 순간(destory)에 뭔가를 실행해주는 것.
useEffect(() => {
console.log("hi :)");
return () => console.log("bye :(");
//consolelog를 출력해주고, 사라질 때 다른 콘솔로그 하나를 return
}, []);
import { useState, useEffect } from "react";
function Hello() {
useEffect(() => {
console.log("hi :)");
return () => console.log("bye :(");
}, []);
return <h1>Hello</h1>;
}
// showing value가 true가 되서 Hello 함수가 렌더링되면,
1. useEffect 콘솔로그 Hi! 실행.
2. 지니고 있던 h1 태그를 실행. (지니고 있기에 hide 버튼 눌렀다가 다시 눌러도 나옴)
2. 실행 시 가지고 있다가, Hello component 소멸 시, bye 콘솔로그 출력.
function App() {
const [showing, setShowing] = useState(false);
const onClick = () => setShowing((prev) => !prev);
// previous value의 상태를 뒤집음. (ex: false 기본값이 true가 되도록)
return (
<div>
{showing ? <Hello /> : null}
// showing value가 true면 위의 'Hello' 함수를 렌더. false면 없음(null)
<button onClick={onClick}>{showing ? "Hide" : "Show"}
// showing value가 true면 "Hide" 출력, false면 "Show" 출력
</button>
</div>
);
}
Vanila JS 강의에서 했던 To-Do List 생성을 React에서 하는 것.
바닐라에서는 html, .jss 파일 두개를 왔다 갔다 해야했지만
여기서는 한 곳에서 끝낼 수 있음
[1, 2, 3, 4,].map
array에 뭘 추가하거나 변경하고 싶을 때
뒤에 .map() 함수를 추가시켜 주면 array의 모든 item에 대해서 실행됨
ex:) [1, 2, 3 ,4].map((item) => ":)");
-> [:), :), :), :)]로 전부 바뀜
※ .map을 쓰고 뒤에 처음 쓰는 태그에 key 값을 지정해줘야 함!
function App() {
const [toDo, setToDo] = useState("");
const [toDos, setToDos] = useState([]);
const onChange = (event) => setToDo(event.target.value);
const onSubmit = (event) => {
event.preventDefault();
if (toDo === "") {
return;
// 아무것도 안쓴 상태로 제출되면 함수 실행을 그냥 죽이는 것
}
setToDo("");
// ToDo의 값을 비움
setToDos((currentArray) => [toDo, ...currentArray]);
// toDos 기본값은 빈 array.
// submit 될 때 OnChange 변수 덕에 return받은 toDo 값과
// 기존의 다른 값들 (...으로 씀) + argument에 대응되는 새로운 값을
// 합쳐서 새로운 배열을 toDos에 저장시킴
};
console.log(toDos);
return (
<div>
<h1>My To Dos ({toDos.length})</h1>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={toDo}
type="text"
placeholder="Write your to do..."
/>
<button>Add To Do</button>
</form>
<hr />
<ul>
{toDos.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
// Todos에 계속 갱신되는 array의 item들을 li로 보여줌
</div>
);
}
- Loading.... 이라는 메세지를 출력
- 'useEffect' 함수로 가상화폐들 정보가 담긴 api를 호출 함
- api 파일 속 정보가 9천개가 넘어 로딩에 시간이 걸림
- 로딩이 끝나면 'Loading....'의 출력을 false로 만듬.
- api의 json에서 우리가 설정한 정보들이 선택창으로 출력됨.
function App() {
const [loading, setLoading] = useState(true);
const [coins, setCoins] = useState([]);
const [bucksIgot, setBucksIgot] = useState();
const onChange = (event) => setBucksIgot(event.target.value);
useEffect(() => {
fetch("https://api.coinpaprika.com/v1/tickers")
.then((response) => response.json())
.then((json) => {
setCoins(json);
setLoading(false);
});
}, []);
return (
<div>
<h1>The Coins! {loading ? "" : `(${coins.length})`}</h1>
// loading의 기본 값이 true. 즉, api가 로딩되면 뒤에 명령이 실행됨
// loading 기본 값이 true라 'Loading...' 메세지 출력됨
useEffect 실행으로 loading이 false가 되고 아래의 명령이 실행 됨
{loading ? (
<strong>Loading...</strong>
) : (
<div>
<select>
{coins.map((coin) => (
<option>
{coin.name} ({coin.symbol}): {coin.quotes.USD.price} USD
</option>
))}
</select>
<div>
<label htmlFor="Igot">I got</label>
<input
value={bucksIgot}
onChange={onChange}
id="Igot"
placeholder="Write how much you got"
type="number"
/>
<span>USD</span>
</div>
<select>
{coins.map((koin) => (
<option>
{bucksIgot / koin.quotes.USD.price} ({koin.symbol})
</option>
))}
</select>
</div>
)}
</div>
);
}