react state
unit converter
array.filter(Boolean)
state๋ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ๊ณณ์ ๋งํ๋ค.
๋ฐ๋๋ผ JS ์ฝ๋์์๋ counter๋ฅผ ์ฆ๊ฐ์ํค๊ณ ์ด๋ฅผ UI์ ๋์คํ๋ ์ด ํ๊ณ ์๋ค.
์ด๋ ๋ฐ๋๋ ๋ฐ์ดํฐ๊ฐ ํ ๋น๋๋ counter ๋ณ์๋ฅผ state๋ก ๋ง๋ค ์ ์๋ค.
๋จผ์ , state๋ฅผ ์ฌ์ฉํ์ง ์๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
const root = document.getElementById("root");
let counter = 0;
function countUp () {
counter++; // 3. counter ๊ฐ์ ์ฌ๋ฆฌ๊ณ
render(); // 4. ๋ฐ๋ counter ๊ฐ์ ๊ฐ์ง๋ App ์ปดํฌ๋ํธ๋ฅผ ๋ค์ render ํ๋ค
}
function render () {
ReactDOM.render(<App />, root);
}
function App() {
return (
<div>
<h3>Total Click: {counter}</h3>
<button onClick={countUp}>ํด๋ฆญ</button>
</div>
);
} // 2. ๋ฒํผ์ ํด๋ฆญํ ๋๋ง๋ค ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์คํ๋๋ค.
render(); // 1. ์ฒ์ App ์ปดํฌ๋ํธ๋ฅผ render ํ์ฌ ํ๋ฉด์ ๋ณด์ฌ์ค๋ค
๋ค๋ง, ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ๋๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ฆฌ๋ ๋๋ง ํ๊ธฐ ์ํด ReactDOM.render() ํจ์๋ฅผ ํธ์ถํด์ผ๋ง ํ๋ค.
๐ก React JS์์์ ๋ฆฌ๋ ๋๋ง
๋ฐ๋๋ผ JS ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ง์ ํ ์์ ์ ์ฒด๊ฐ ์ ๋ฐ์ดํธ ๋๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด ์ดํด๋ณด๋ฉด span.innerText์ ์ํด counter ๋ณ์๋ง์ด ์๋๋ผ 'Total Click' ํ ์คํธ๊น์ง ํฌํจํ์ฌ span ์์ ์ ์ฒด๊ฐ ์ ๋ฐ์ดํธ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.๋ฐ๋ฉด์, React JS๋ฅผ ์ฌ์ฉํ๋ฉด UI์์ ๋ฐ๋ ๋ถ๋ถ๋ง์ ์ ๋ฐ์ดํธ ํ ์ ์๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด ์ดํด๋ณด๋ฉด counter ๋ณ์์ ํด๋นํ๋ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธ ๋๋ ๊ฒ์ ์ ์ ์๋ค.
React JS๋ ์ด์ ์ ๋ ๋๋ง๋ ์ปดํฌ๋ํธ๊ฐ ๋ฌด์์ธ์ง๋ฅผ ํ์ธํ๊ณ , ๋ค์์ ๋ ๋๋ง๋ ์ปดํฌ๋ํธ๋ ๋ฌด์์ธ์ง๋ฅผ ํ์ธํ์ฌ, ๋ฐ๋ ๋ถ๋ถ๋ง์ ์ ๋ฐ์ดํธ ํด์ค๋ค.
๋ค์ ๋งํด, CountUp ํจ์์ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พผ ํ ๋ฆฌ๋ ๋๋ง ํ๊ฒ ๋๋ฉด ๋ฐ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๋
App ์ปดํฌ๋ํธ ์ ๋ถ๊ฐ ์ฌ์์ฑ
๋์ด root์ ๋ฐฐ์น๋์ง๋ง, ์ค์ ๋ก๋ ์ค๋ก์งcounter ๋ณ์๋ง์ด ๋ฐ๋ ๋ฟ์ด๋ค.
์ด๋ ์ธํฐ๋ ํฐ๋ธํ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ง๋๋ ๋ฐ ๋งค์ฐ ํฐ ๋์์ด ๋๋ค.
React.useState()๋ฅผ ์ฌ์ฉํ๋ฉด (render ํจ์๋ฅผ ๊ณ์ ํธ์ถํ ํ์ ์์ด) React JS ์ดํ ๋ด์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ด
ํ๊ณ , ์๋์ผ๋ก ๋ฆฌ๋ ๋๋ง
์ ์ผ์ผํฌ ์ ์๋ค.
const App = () => {
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter(counter + 1);
};
return (
<div>
<h3>Total Click: {counter}</h3>
<button onClick={onClick}>ํด๋ฆญ</button>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
React.useState()
์ ๋ฐฐ์ด์ return ํ๋ฉฐ, ์ธ์๋ก๋ ๋ฐ์ดํฐ์ ์ด๊ธฐ๊ฐ์ ์ ๋ฌํ ์ ์๋ค.
counter๋ ๋ฐ์ดํฐ, setCounter๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๋ฐ ์ฌ์ฉ๋๋ ํจ์์ด๋ค.
const [counter, setCounter] = React.useState(0);
// ์์ ์๋๋ ๊ฐ์ ์ฝ๋์ด๋ค
const data = React.useState(0);
const counter = data[0];
const setCounter = data[1];
React.useState()๊ฐ ๋ฐํํ๋ ๋ฐฐ์ด์ ๋ ๋ฒ์งธ ์์
์ธ setCounter ํจ์๋, counter ๋ณ์์ ๊ฐ์ ๋ฐ๊พผ ํ, ์ด๋ฅผ ์๋์ผ๋ก ๋ฆฌ๋ ๋๋ง๊น์ง ํด์ค๋ค.
const OnClick = () => {
setCounter(counter + 1);
};
// ์์ ์๋๋ ๊ฐ์ ์ฝ๋์ด๋ค
const OnClick = () => {
counter++;
ReactDOM.render(<Container />, root);
};
๐ก React JS์์์ ๋ฆฌ๋ ๋๋ง
(1)๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ง์ฐฌ๊ฐ์ง๋ก UI์์ ๋ฐ๋ ๋ถ๋ถ๋ง์ ์ ๋ฐ์ดํธ ํ ์ ์๋ค.
App ์ปดํฌ๋ํธ์ state, ์ฆ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ๊ฐ ๋ฐ๋๋ฉด App ์ปดํฌ๋ํธ ์ ๋ถ๋ฅผ ์ฌ์์ฑ(๋ฆฌ๋ ๋๋ง)ํ๋ค.
(App ํจ์์์ return ํ๊ธฐ ์ ์ ์ฝ์ ๋ก๊ทธ๋ฅผ ์ถ๊ฐํ๋ฉด ํด๋ฆญํ ๋๋ง๋ค ์ฝ์์ ๊ฐ์ด ์ถ๋ ฅ๋๋ค.)๊ทธ๋ฌ๋ ๋ฌผ๋ก ์ฌ๊ธฐ์๋ ์ค์ ๋ก๋ ์ค๋ก์ง
counter ๋ณ์๋ง์ด ๋ฐ๋ ๋ฟ์ด๋ค.
(๊ฐ๋ฐ์ ๋๊ตฌ์ elements ํญ์ ์ดํด๋ณด๋ฉด ๋ฒํผ์ ํด๋ฆญํ ๋๋ง๋ค counter ๋ณ์ ๋ถ๋ถ๋ง์ด ๋ณํ๋ค.)
๐ ์ด์ ๋จ๊ณ์ state๋ฅผ ์ด์ฉํด์ ๋ค์ ๋จ๊ณ์ state ๋ฐ๊พธ๊ธฐ
state๋ฅผ ์ค์ ํ๋ ๋ฐ๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
ํ๋๋ ์ง์ state ๊ฐ์ ์ ๋ ฅํด์ฃผ๋ ๊ฒ์ด๊ณ (ex.setCounter(333)
), ๋ค๋ฅธ ํ๋๋ ์ด์ ๋จ๊ณ์ state๋ฅผ ์ด์ฉํด ๋ค์ ๋จ๊ณ์ state๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ด๋ค.(ex.setCounter(counter + 1)
)const onClick = () => { // setCounter(counter + 1); setCounter(current => current + 1); };
์์์๋ ์ด์ ๋จ๊ณ์ state๋ฅผ ์ด์ฉํด์ ๋ค์ ๋จ๊ณ์ state๋ฅผ ๋ฐ๊พธ๊ธฐ ์ํด
setCounter(counter + 1)
๋ฅผ ์คํํ๋ค.
๊ทธ๋ฌ๋ ์ด๋ ๊ฒ ์์ฑํ๋ฉด ์๊ธฐ์น ๋ชปํ๊ฒ ๋ค๋ฅธ ๊ณณ์์ state๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ์์๊ณผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ์๋ ์๋ค.
๋์ ์setCounter(current => current + 1)
์ ์คํํ๋ ๊ฒ์ด ๋ ์์ ํ๋ค.
for๊ณผ class๋ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ์กด์ฌํ๋ ์์ฝ์ด์ด๊ธฐ ๋๋ฌธ์ JSX ์ฝ๋์์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด ์๋ฌ๊ฐ ๋ฌ๋ค.
๋์ ์ JSX ๋ฌธ๋ฒ์ ๋ฐ๋ผ htmlFor๊ณผ className์ ์ฌ์ฉํด์ผ ํ๋ค.
React JS ์ธ๊ณ์์ ์์ฑํ input์ value๋ ์ง์ ํต์ ํ ์ ์๋ค.(uncontrolled input)
๋ฐ๋ผ์, state๋ฅผ ๋ง๋ค์ด์ input์ value ์์ฑ์ผ๋ก ์ ํด์ค ํ(์ด๋ React.useState()์ ์ธ์๋ก ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํด์ผ ๊ฒฝ๊ณ ๊ฐ ์๋ธ) ์ฌ์ฉ์๊ฐ input์ ๋ค๋ฅธ ๊ฐ์ ์ ๋ ฅํ ๋๋ง๋ค input์ value๋ฅผ ์ ๋ฐ์ดํธ ํ์ฌ(onChange ํจ์) ๊ทธ ๊ฐ์ ์ธ๋ถ์์ ๊ฐ์ ธ์ค๋๋ก ํด์ผ ํ๋ค.({minutes} ์ด์ฉ)
input์ value๋ฅผ state์ ์ฐ๊ฒฐ์ํด์ผ๋ก์จ, input์ value๋ฅผ ์ธ๋ถ์์๋ ์์ ํ ์ ์๋ค.
const App = () => {
const [minutes, setMinutes] = React.useState(0);
const onChange = (event) => setMinutes(event.target.value);
return (
<div>
<label htmlFor="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
/>
<label htmlFor="hours">Hours</label>
<input id="hours" placeholder="Hours" type="number" />
<h4>minutes input์ value๋ {minutes} ์
๋๋ค</h4>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
onChange ํจ์ ์์์ console.log(event) ๋ฅผ ์คํํ๋ฉด ์ฝ์ ์ฐฝ์ SyntheticBaseEvent ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ๋๋ค.
์ด๋ nativeEvent๋ฅผ ๊ฐ์ง๋๋ฐ ์ด ์์ target์ด input์ ์๋ฏธํ๊ณ target์ value๋ฅผ ๊ฐ์ง๋ค.
์ฆ, console.log(event.target.value
) ๋ฅผ ์คํํ๋ฉด ์ฝ์ ์ฐฝ์ input์ value
๊ฐ ์ถ๋ ฅ๋๋ค.
์ด์ setMinutes ํจ์๋ฅผ ์ด์ฉํด minutes๋ฅผ ์
๋ฐ์ดํธ ํ ํ Appp ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌ๋ ๋๋งํด์ผ ํ๋ค.
์ด์ minutes input์ ์ฌ์ฉ์๊ฐ ๊ฐ์ ์ ๋ ฅํ์ฌ input์ value๊ฐ ๋ณํ ๋๋ง๋ค ๊ทธ ๋ณํ๊ฐ h4์ ์ค์๊ฐ์ผ๋ก ๋ฐ์๋์ด ๋ณด์ด๊ฒ ๋๋ค.
๐ก ์ด๋ onChange={onChange} ์ฝ๋๋ฅผ ์ญ์ ํ๋ฉด ์๋ฌด๋ฆฌ minutes input์์ ํค๋ณด๋๋ฅผ ๋๋ฌ ๊ฐ์ ์ ๋ ฅํด๋ input ์ฐฝ์๋ ๊ณ์ 0๋ง ๋ณด์ธ๋ค.
์ด๋ ์๋ input์ value์ธ {minutes}์ ๊ธฐ๋ณธ๊ฐ์ 0์ผ๋ก ์ค์ ํ ํ
์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ฅผ ๋๋ฌ ๊ฐ์ ๋ณ๊ฒฝํ ๋๋ง๋ค onChange ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ์ํด minutes ๊ฐ์ด ๋ณ๊ฒฝ๋จ์ผ๋ก์จ
input์ value๋ ๋ณ๊ฒฝ๋๊ณ App ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋๋ก ํ๋๋ฐonChange ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ญ์ ํ๊ธฐ ๋๋ฌธ์ minutes์ ๊ฐ์ด 0์ธ ์ํ์์ ์ ๋ฐ์ดํธ ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ค์ ๋งํด, minutes input์ ๊ฒฝ์ฐ โ ๋จผ์ change event๋ ๋ฆฌ์ค๋ ํด์ผ ํ๊ณ , โก change event๊ฐ ๋ฐ์ํ์ ๋ input์ value๋ฅผ ์ ๋ฐ์ดํธ ํ๊ณ UI์ ๋ณด์ฌ์ฃผ๊ธฐ๋ ํด์ผ ํ๋ค.
hours input์ ๊ฒฝ์ฐ input ์ฐฝ์ ์์ ํ ์ ์๋๋ก change event๋ฅผ ๋ฆฌ์ค๋ํ์ง ์๊ฒ๋ ํ๋ค.
const App = () => {
const [minutes, setMinutes] = React.useState(0);
const onChange = (event) => setMinutes(event.target.value);
const onClick = () => setMinutes(0); // reset ๋ฒํผ ํด๋ฆญ ์ minutes(input์ value) ์ด๊ธฐํ
return (
<div>
<h1>Super Converter</h1>
<div>
<label htmlFor="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}
/>
</div>
<div>
<label htmlFor="hours">Hours</label>
<input
value={Math.round(minutes / 60)} // ๋จ์ ๋ณํ
id="hours"
placeholder="Hours"
type="number"
/>
</div>
<button onClick={onClick}>Reset</button>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
๊ธฐ๋ณธ์ ์ผ๋ก hours input์ disabled๋ฅผ ์ ์ฉํ๊ณ minutes input์ enabled ์ํ๋ก ๋๋ค.
state๋ฅผ ํ๋ ๋ ๋ง๋ค์ด flip ๋ฒํผ์ ๋๋ฅด๋ฉด flipped ๋ณ์์ ๊ฐ์ด ๋ฐ๋๊ฐ ๋๋๋ก ํ๋ค.
const App () => {
...
const [flipped, setFlipped] = React.useState(false); // ๊ธฐ๋ณธ๊ฐ false
const onFlip = () => setFlipped(current => !current); // flipped ๋ณ์ ๊ฐ ์
๋ฐ์ดํธ & App ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง
return (
<div>
<div>
<label htmlFor="minutes">Minutes</label>
<input
id="minutes"
...
disabled={flipped} // {flipped === true} ์ ๊ฐ๋ค
/>
</div>
<div>
<label htmlFor="hours">Hours</label>
<input
id="hours"
...
disabled={!flipped} // {flipped === false} ์ ๊ฐ๋ค
/>
</div>
...
<button onClick={onFlip}>{flipped ? "Turn back" : "Flip"}</button>
</div>
);
};
minutes input์ ๊ฐ์ ์
๋ ฅํ์ ๋์๋ง hours input์ {Math.round(minutes / 60)}์ ๊ฐ์ด ๋ณด์ฌ์ง๋๋ก ํ๊ณ , hours input์ ๊ฐ์ ์
๋ ฅํ์ ๋๋ hours input์ ์
๋ ฅํ ๊ฐ์ ๊ทธ๋๋ก ๋ณด์ฌ์ฃผ๋๋ก ํด์ผ ํ๋ค.
minutes input์ ๊ฒฝ์ฐ์๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค.
์ด๋ฅผ ์ํด flipped ๋ณ์์ ๊ฐ์ ์ด์ฉํด ์กฐ๊ฑด๋ถ ์ผํญ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ก ์์
ํ ์ ์๋ค.
์ฝ๋์ ํผ๋์ ํผํ๊ธฐ ์ํด ์์์ ์ ์ธํ minutes๋ฅผ amount๋ก, setMinutes๋ฅผ setAmount๋ก ๋ฐ๊ฟ์ฃผ์๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ์์ฑํ๋ฉด ๋ฌธ์ ๊ฐ ํ๋ ์๋ค.
flip ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํ์ฑํ๋ input์ value์ amount ๋ณ์์ ๊ฐ์ด ํ ๋น๋์ด ๋ณด์ด๊ฒ ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด onFlip ํจ์์ reset() ์ฝ๋๋ฅผ ์ถ๊ฐ
ํ๋ค.
const onFlip = () => {
setAmount(current => !current);
reset();
};
...
<input
value={!flipped ? amount : amount * 60}
id="minutes"
...
disabled={flipped}
/>
...
<input
value={flipped ? amount : Math.round(amount / 60)}
id="hours"
...
disabled={!flipped}
/>
const array = [1, "hi", null, ``, false];
const truthyCount = array.filter(Boolean).length;
// ์ ์๋๋ ๊ฐ์ ์ฝ๋์ด๋ค.
// Boolean()์ ๊ทธ ์ธ์๊ฐ true์ผ ๋ true๋ฅผ, false์ผ ๋ false๋ฅผ ๋ฆฌํดํ๋ ํจ์์ด๋ค.
const truthyCount = array.filter((item) => Boolean(item)).length;
console.log(truthyCount); // ๋ฐฐ์ด [1, "hi"]์ ๊ธธ์ด๋ 2