npx create-react-app .
다음 파일을 전부 삭제한다.
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
import "./App.css";
function App() {
return <div className="App"></div>;
}
export default App;
npm run start
UI는 사용자 인터페이스라는 뜻으로, 웹 페이지에서 사용자와 상호작용하는 요소를 말한다.
const Viewer = () => {
return (
<div>
<div>현재 카운트: </div>
<h1>0</h1>
</div>
);
};
export default Viewer;
import "./App.css";
import Viewer from "./component/Viewer";
function App() {
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<Viewer />
</section>
</div>
);
}
export default App;
const Controller = () => {
return (
<div>
<button>-1</button>
<button>-10</button>
<button>-100</button>
<button>+100</button>
<button>+10</button>
<button>+1</button>
</div>
);
};
export default Controller;
import "./App.css";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<Viewer />
</section>
<section>
<Controller />
</section>
</div>
);
}
export default App;
body {
padding: 20px;
}
.App {
margin: 0 auto;
width: 500px;
}
.App > section {
padding: 20px;
background-color: rgb(245, 245, 245);
border: 1px solid rgb(240, 240, 240);
border-radius: 5px;
margin-bottom: 10px;
}
import "./App.css";
import { useState } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const handleSetCount = (value) => {
setCount(count + value);
};
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;
const Viewer = ({ count }) => {
return (
<div>
<div>현재 카운트 : </div>
<h1>{count}</h1>
</div>
);
};
export default Viewer;
const Controller = ({ handleSetCount }) => {
return (
<div>
<button onClick={() => handleSetCount(-1)}>-1</button>
<button onClick={() => handleSetCount(-10)}>-10</button>
<button onClick={() => handleSetCount(-100)}>-100</button>
<button onClick={() => handleSetCount(100)}>+100</button>
<button onClick={() => handleSetCount(10)}>+10</button>
<button onClick={() => handleSetCount(1)}>+1</button>
</div>
);
};
export default Controller;
라이프 사이클 제어 (Lifecylcle Control): 라이프 사이클을 이용하여 여러 유용한 작업을 실행하는 것을 말한다.
import { useState, useEffect } from "react";
(...)
function App() {
const [count, setCount] = useState(0);
const handleSetCount = (value) => {
setCount(count + value);
};
useEffect(() => {
console.log("count 업데이트: ", count);
}, [count]);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;
useEffect의 용법
useEffect(callback, [deps])
콜백 함수 의존성 배열
(...)
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => {
console.log("업데이트: ", text, count);
}, [count, text]);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;
(...)
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => {
console.log("컴포넌트 업데이트");
});
(..)
}
export default App;
리렌더 될 때만 콜백 함수를 실행시키기
import { useRef, useState, useEffect } from "react";
(...)
function App() {
(...)
const didMountRef = useRef(false);
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
(...)
}
export default App;
조건문 자세히 보기
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
(...)
function App() {
(...)
const didMountRef = useRef(false);
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
useEffect(() => {
console.log("컴포넌트 마운트");
}, []);
return (
(...)
);
}
export default App;
(...)
function App() {
(...)
useEffect(() => {
setInterval(() => {
console.log("깜빡");
}, 1000);
});
(...)
}
export default App;
매우 빠른 속도로 ‘깜빡’ 문자열이 콘솔에 출력되는 이유
useEffect의 클린업 기능 사용하기
(...)
function App() {
(...)
useEffect(() => {
const intervalID = setInterval(() => {
console.log("깜빡");
}, 1000);
return () => {
console.log("클린업");
clearInterval(intervalID);
};
});
(...)
}
export default App;
! 지금 작성한 useEffect를 모두 삭제 또는 주석 처리를 한다.
function Even() {
return <div>현재 카운트는 짝수입니다</div>;
}
export default Even;
(...)
import Even from "./component/Even";
function App() {
(...)
return (
<div className="App">
(...)
<section>
<Viewer count={count} />
{count % 2 === 0 && <Even />}
</section>
(...)
</div>
);
}
export default App;
컴포넌트가 언마운트될 때 콘솔에 특정 문자열을 출력하게 해 보자
import { useEffect } from "react";
function Even() {
useEffect(() => {
return () => {
console.log("Even 컴포넌트 언마운트");
};
}, []);
return <div>현재 카운트는 짝수입니다</div>;
}
export default Even;
컴포넌트 트리 살펴보기
1. <section> 안에 AND 단축 평가를 활용하여 count의 값이 홀수일 때 Even 함수가 출력되도록 App.js를 수정해 봐라.
function Even() {
return <div>현재 카운트는 홀수입니다</div>;
}
export default Even;
(...)
import Even from "./component/Even";
function App() {
(...)
return (
<div className="App">
(...)
<section>
{/* 이곳에 작성하시오 */}
</section>
(...)
</div>
);
}
export default App;
2. didMountRef 변수를 활용하여 주어진 함수가 리렌더 될 때만 실행되도록 수정해 봐라.
useEffect(() => {
console.log("컴포넌트 업데이트");
});
(...)
import Even from "./component/Even";
function App() {
(...)
return (
<div className="App">
(...)
<section>
{count % 2 === 1 && <Even />}
</section>
(...)
</div>
);
}
export default App;
2. 정답
const didMountRef = useRef(false);
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트");
}
});
이정환, 『한 입 크기로 잘라먹는 리액트』, 프로그래밍인사이트(2023).
Editor: 숨숨
[리액터 스타터2] project 2 [할 일 관리] 앱 만들기 1 (0) | 2023.12.01 |
---|---|
[리액터 스타터2] Hooks (1) | 2023.11.24 |
[리액트 스타터2] 5장. 리액트의 기본 기능 다루기(2) (0) | 2023.11.10 |
[리액트 스타터2] 5장. 리액트의 기본 기능 다루기(1) (1) | 2023.11.03 |
[리액트 스타터2] 4장. 리액트 시작하기 (0) | 2023.10.13 |