: 화면의 렌더링을 하기 위한 데이터
: 데이터가 바뀌면 화면이 바뀐다
: useState, useEffect (Hooks)
명령형 프로그래밍
'안녕'을 찾아 'hi'로 바꾸기
-> hellodiv 찾아서
-> innterText를 '하이'
선언형 프로그래밍
'안녕' -> 'hi'
// 구조 분해 할당
// 배열을 변수로 다시 할당할 수 있다.
// 배열은 순서가 중요, 변수명은 직접 정함.
const arr = [1, 2];
const [one, two] = arr;
console.log(one);
console.log(two);
// 오브젝트도 가능.
// 오브젝트는 순서가 상관 X, 변수 명이 중요함.
const obj = {
name : "홍길동",
age : 12,
};
const {name, age} = obj;
console.log(name);
console.log(age);
선언형 프로그래밍이 가능해짐.
선언만 해놓으면, 알아서 데이터가 찾아서 들어감.
import { useState } from "react";
function App() {
// useState는 리액트에서 상태를 관리하는 함수.
// 리턴 값은 배열이고,
// 배열의 첫 요소는 값, 두번째 요소는 값을 변경하는 함수이다.
// useState의 매개변수는 값의 초기값 (현재 0)
const [count, setCount] = useState(0);
const increase = () => {
// 매개변수로 함수와 값 그 자체를 넣을 수 있다.
// 함수 추천.
setCount(prev => prev + 1);
// setCount(count + 1);
}
return (
<div>
<div>{count}</div>
<button onClick={increase}>+</button>
</div>
);
}
export default App;
setCount는
const increase = () => {
// 매개변수로 함수와 값 그 자체를 넣을 수 있다.
// 함수 추천.
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// setCount가 포함된 함수가 실행이 끝나야 set이 한 번 실행됨.
// setCount(count + 1); // count가 1에서 2가 되는 게 아님.
// setCount(count + 1); // 여기 넘어올 떈 count는 1 (set이 되지 않음)
// 즉 끝날 때는 count = 2.
}
function Item(props){
return (
<li>{props.data}</li>
);
}
export default Item;
import { useState } from "react";
import Item from "./Item";
function App1(){
const [searchValue, setSerachValue] = useState("");
const randomNumber = Math.random();
const gameList = ["메이플스토리", "리그오브레전드", "서든어택", "배틀그라운드"];
// 함수를 빼는 걸 선호. (태그가 길어져서 그런가?)
const changeSearchValue = event => {
setSerachValue(prev => event.target.value)
}
return <div>
<div>{randomNumber}</div>
<input value={searchValue} placeholder="검색어를 입력해주세요" onChange={changeSearchValue}/>
<ul>{gameList.filter(el => el.includes(searchValue)).map((el, index) => <Item key={index} data={el}/>)}</ul>
</div>
}
export default App1;
function App2(){
const randomNumber = Math.random();
return(
<div>
<hr />
<div>두번째 컴포넌트</div>
<div>{randomNumber}</div>
</div>
);
}
export default App2;
import { useEffect, useState } from "react";
import Item from "./Item";
function App1(){
// state가 변경되면 index.js에서 호출한 App1 컴포넌트를 새로 호출한다.
const [searchValue, setSerachValue] = useState("");
// 즉, state 변경 마다 App1() 함수가 실행(렌더링)되고,
// randomNumber의 값도 바뀌게 된다.
const randomNumber = Math.random();
// 그래서 렌더링 될 때마다 변경되면 안되는 변수는,
// 이렇게 state로 변수를 설정해야 한다.
// const [randomNumber] = useState(Math.random());
// 원칙상, 컴포넌트 내부 변수는 state로 만드는 것이 좋다.
// 하지만, 변수를 새로 만드는 것이 state로 설정하는 것보다 빠를 수 있고
// 그 경우에는 고정적으로.
const gameList = ["메이플스토리", "리그오브레전드", "서든어택", "배틀그라운드"];
// 함수를 빼는 걸 선호. (태그가 길어져서 그런가?)
const changeSearchValue = event => {
setSerachValue(prev => event.target.value)
}
return <div>
<div>{randomNumber}</div>
<input value={searchValue} placeholder="검색어를 입력해주세요" onChange={changeSearchValue}/>
<ul>{gameList.filter(el => el.includes(searchValue)).map((el, index) => <Item key={index} data={el}/>)}</ul>
</div>
}
export default App1;
useState로 선언한 변수, 즉 '상태'가 변경 시마다 재 렌더링,
그래서 특정 데이터가 필요한 영역을 구분지어 컴포넌트를 짜고, 그 컴포넌트만 재 렌더링 되도록 한다.
이게 React의 역할.
rest api 요청 주소
https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20230930
(2023년 9월 30일 데이터)
useEffect(실행할 함수, 감지할 상태 리스트);
// searchValue가 바뀔 때마다 함수가 실행.
useEffect(() => {
console.log(searchValue);
}, [searchValue]);
// 렌더링 이후 실행되는 훅스
// 페이지가 열릴 때 딱 한 번만 실행됨.
// useEffect(실행할 함수, 감지할 상태 리스트);
useEffect(() => {
// console.log("통신");
fetch("https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20230930")
.then((res) => res.json())
.then((result) => {
console.log(result)
setMovieList(prev => result.boxOfficeResult.dailyBoxOfficeList);
})
.catch((error) => {
console.log(error)
});
}, []);
import { useEffect, useState } from "react";
import Item from "./Item";
function App1(){
// state가 변경되면 index.js에서 호출한 App1 컴포넌트를 새로 호출한다.
const [searchValue, setSerachValue] = useState("");
// 즉, state 변경 마다 App1() 함수가 실행(렌더링)되고,
// randomNumber의 값도 바뀌게 된다.
const randomNumber = Math.random();
// 그래서 렌더링 될 때마다 변경되면 안되는 변수는,
// 이렇게 state로 변수를 설정해야 한다.
// const [randomNumber] = useState(Math.random());
// 원칙상, 컴포넌트 내부 변수는 state로 만드는 것이 좋다.
// 하지만, 변수를 새로 만드는 것이 state로 설정하는 것보다 빠를 수 있고
// 그 경우에는 고정적으로.
const [movieList, setMovieList] = useState([]);
// 함수를 빼는 걸 선호. (태그가 길어져서 그런가?)
const changeSearchValue = event => {
setSerachValue(prev => event.target.value)
}
// 렌더링 이후 실행되는 훅스
// 페이지가 열릴 때 딱 한 번만 실행됨.
// useEffect(실행할 함수, 감지할 상태 리스트);
useEffect(() => {
// console.log("통신");
fetch("https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20230930")
.then((res) => res.json())
.then((result) => {
console.log(result)
setMovieList(prev => result.boxOfficeResult.dailyBoxOfficeList);
})
.catch((error) => {
console.log(error)
});
}, []);
// searchValue가 바뀔 때마다 함수가 실행.
useEffect(() => {
console.log(searchValue);
}, [searchValue]);
return <div>
<div>{randomNumber}</div>
<input value={searchValue} placeholder="검색어를 입력해주세요" onChange={changeSearchValue}/>
<ul>{movieList.filter(el => el.movieNm.includes(searchValue)).map((el, index) => <Item key={index} data={el.movieNm}/>)}</ul>
</div>
}
export default App1;