State
- state: 데이터가 저장되는 곳
- 아래 예시에서 counter의 숫자 부분을 state로 대체 가능
- 버튼을 누를 때 전체가 render되게 됨
- 이렇게 구현해도 개발자 도구로 버튼을 누를 때마다 바뀌는 부분을 확인하면, 해당 부분 숫자만 바뀌는 것을 확인할 수있음 - react 짱
<!DOCTYPE html>
<html lang="en">
<head>
<title>Begin React</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
let counter = 0;
function countUp() {
counter = counter + 1;
render();
}
function render() {
ReactDOM.render(<Container />, root);
}
const Container = () => (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>
);
ReactDOM.render(<Container />, root);
</script>
</html>
조금 더 rendering을 편하게 하는 방법은 없을까?
useState
[추가팁] JS 문법
const food = ["tomato", "potato"];
const [myFavFood, mySecondFavFood] = food;
// same as myFavFood = food[0];, mySecondFavFood = food[1];
// myFavFood
// 'tomato'
useState를 사용해서 바뀐 부분과 함께 render
const [counter, setCounter] = React.useState(0);
const onClick = () => {
// modifier function은 값을 변화시킨 다음에 rerender 시켜줌
setCounter(counter + 1);
};
modifier function alpha; 변수를 통한 직접적인 값 변화보다는 함수로 처리하는 것이 더 안전
const [counter, setCounter] = React.useState(0);
const onClick = () => {
// modifier function은 값을 변화시킨 다음에 rerender 시켜줌
// setCounter(counter + 1);
setCounter((current) => current + 1);
};
최종 코드
<!DOCTYPE html>
<html lang="en">
<head>
<title>Begin React</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [counter, setCounter] = React.useState(0);
const onClick = () => {
// modifier function은 값을 변화시킨 다음에 rerender 시켜줌
// setCounter(counter + 1);
setCounter((current) => current + 1);
};
return (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={onClick}>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
</html>
유의 사항
JSX를 사용할 때는 JSX에 맞는 프로퍼티를 사용해야 함
- class -> className
- for -> htmlFor
React는 SyntheticBaseEvent를 발생시킴, 그 안에 nativeEvent 속성 값이 있음
분을 시간으로 환산해주는 계산기 만들어보기
- minutes에 값을 입력하면 hour로 변환
- input에 값을 입력 시, onChange 이벤트가 발생
- onChange 이벤트는 setMinutes()를 작동
<!DOCTYPE html>
<html lang="en">
<head>
<title>Begin React</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [minutes, setMinutes] = React.useState(0);
const onChange = (event) => {
// console.log(event.target.value);
setMinutes(event.target.value);
};
const reset = () => setMinutes(0);
return (
<div>
<h1>Super Converter</h1>
<label htmlFor="minutes">Minutes</label>
<input
id="minutes"
placeholder="Minute"
type="number"
value={minutes}
onChange={onChange}
/>
<br></br>
<label htmlFor="hours">Hours</label>
<input
id="hours"
placeholder="Hours"
type="number"
disabled
value={Math.round(minutes / 60)}
/>
<br></br>
<button onClick={reset}>Reset</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
</html>
시간도 분으로 계산할 수 있도록 개선해보기
- hour input 태그에도 onChange 함수 적용
- onFlip 이라는 변수로 현재 flipped된 상태인지 아닌지 구분
- tenary syntax로 onFlip 변수의 상태마다 value 값이 다르게 출력될 수 있도록 함
- tenary syntax로 onFlip 변수의 상태마다 disabled가 적용될 수 있도록 함
- tenary syntax로 onFlip 변수의 상태마다 button의 value 값이 적용될 수 있도록 함
<!DOCTYPE html>
<html lang="en">
<head>
<title>Begin React</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.9/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [amount, setAmount] = React.useState(0);
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
// console.log(event.target.value);
setAmount(event.target.value);
};
const reset = () => setAmount(0);
// const onFlip = () => setflip(!flipped);
const onFlip = () => {
setFlipped((current) => !current);
reset();
};
return (
<div>
<h1>Super Converter</h1>
<label htmlFor="minutes">Minutes</label>
<input
id="minutes"
placeholder="Minute"
type="number"
onChange={onChange}
value={flipped ? amount * 60 : amount}
disabled={flipped}
/>
<br></br>
<label htmlFor="hours">Hours</label>
<input
id="hours"
placeholder="Hours"
type="number"
onChange={onChange}
value={flipped ? amount : Math.round(amount / 60)}
disabled={flipped === false}
/>
<br></br>
<button onClick={reset}>Reset</button>
<button onClick={onFlip}>
{flipped ? "Minutes to Hours" : "Hours to Minutes"}
</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
</html>
Class 사용 예시
import React from "react";
class App extends React.Component {
state = {
count: 0,
};
plus = () => {
this.setState((current) => ({ count: current.count + 1 }));
};
minus = () => {
this.setState((current) => ({ count: current.count - 1 }));
};
render() {
return (
<div>
<h1>The number is {this.state.count}</h1>
<button onClick={this.plus}>plus</button>
<button onClick={this.minus}>minus</button>
</div>
);
}
}
export default App;