State
state
는 기본적으로 데이터가 저장되는 곳이다.
어떻게 하면 React.js 어플에 값이 바뀔 데이터를 담아줄 수 있을까?
변수들을 JSX로 보내주는 방법은?
let counter = 0;
const Container = () => (
<div>
<h3>Total Clicks: {counter}</h3>
<button>Click me</button>
</div>
);
counter을 증가시키는 UI를 만드려면?
let counter = 0;
function countUp() {
counter = counter + 1;
}
const Container = () => (
<div>
<h3>Total Clicks: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>
);
하지만 위 코드로는 UI가 변하지 않는다. counter
변수는 update되지만, UI를 새로고침해주고 있지 않다.렌더링을 한 번만 해주기 때문이다.
즉, Container
를 리렌더링해서 새로운 버전의 Container
을 보여줘야 한다.
<script type="text/babel">
const root = document.getElementById("root");
let counter = 0;
function countUp() {
counter = counter + 1;
render(); // Container을 리렌더링해줌
}
function render() {
ReactDOM.render(<Container />, root);
}
const Container = () => (
<div>
<h3>Total Clicks: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>
);
render(); // app이 시작될 때 Container 렌더링
</script>
❓왜 최고의 방법이 아닌가?
counter
의 값을 바꿀 때마다 다시 렌더링하는걸 잊으면 안 되기 때문이다!
React.js 앱 내에서 데이터를 보관하고 자동으로 리렌더링할 수 있는 최고의 방법은?
const root = document.getElementById("root");
function App() {
// 아래처럼!!! 이렇게!!
const [counter, modifier] = React.useState(0);
//
return (
<div>
<h3>Total Clicks: {counter}</h3>
<button>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
modifier
👉
modifier
함수는 어떤 값을 부여하던 그 값으로 업데이트하고 리렌더링을 일으킨다. component가 재생성되는 원리임.
- 보통
set{데이터이름}
형태로 이름을 부여한다.- 데이터를 수정하기 위해
modifier
함수를 사용한다면, 그modifier
함수를 사용할 때 컴포넌트는 새로운 데이터와 함께 새로고침된다.
function App() {
const [counter, setCounter] = React.useState(0);
const onClick =() => {
// 여기 modifier 함수!!!
setCounter(counter+1);
};
return (
<div>
<h3>Total Clicks: {counter}</h3>
<button onClick={onClick}>Click me</button>
</div>
);
}
✨modifier
함수를 사용해 state, 즉 어플리케이션의 데이터를 바꿀 때, 컴포넌트 전체가 새로운 값을 가지고 재생성된다.
👉 state가 바뀌면 리렌더링이 일어난다.
state
을 바꾸는 또다른 방법은?setCounter
이용해서 원하는 값을 넣어주기counter
의 state
를 이용해서 새로운 counter
의 state
를 계산한다.counter
는 다른 곳에서도 변경될 수 있다는 점!setCounter(counter+1);
state
를 기반으로 다음 state
를 계산setCounter((current) => current + 1);
이처럼 현재 state
를 기반으로 다음 state
를 계산하고 싶다면 함수를 이용하면 된다!
사용자의 input
을 어떻게 얻는지, form
을 만들었을 때 state
는 어떤식으로 작용하는지?
label
은 input
옆에 써주는 글씨다.
function App() {
return (
<div>
<h1>Super Converter</h1>
<label for="minutes">Minutes</label>
<input id="minutes" placeholder="Minutes" type="number" />
<label for="hours">Hours</label>
<input id="hours" placeholder="Hours" type="number"/>
</div>
);
}
위를 jsx
방식으로 바꿔줘야 한다.
예를 들어 for
, class
는 javascript
용어이기 때문이다.
function App() {
const [minutes, setMinutes] = React.useState();
const onChange=()=>{
console.log("somebody wrote");
};
return (
<div>
<h1 className="hi">Super Converter</h1>
<label htmlFor="minutes">Minutes</label>
<input
// 이를 통해 어디서든 input의 value를 수정할 수 있다.
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}/>
<label htmlFor="hours">Hours</label>
<input id="hours" placeholder="Hours" type="number"/>
</div>
);
}
React.useState()
는 array를 return하는데, 첫 번째 item은 value
이고, 두 번째 item은 이 value
를 수정하고, component
를 새로고침 할 때 쓰는 함수이다.
위의 경우, 👉변화를 감지하면(onChange
), onChange
함수가 실행된다.
function App() {
const [minutes, setMinutes] = React.useState();
const onChange=()=>{
// event.target.value로 input에 들어온 값에 접근할 수 있다!
setMinutes(event.target.value);
};
return (
<div>
<h1 className="hi">Super Converter</h1>
<label htmlFor="minutes">Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="number"
onChange={onChange}/>
<h3>You want to convert {minutes}</h3>
<label htmlFor="hours">Hours</label>
<input id="hours" placeholder="Hours" type="number"/>
</div>
);
}
- ❗
input
의value
를 연결시켜주는 이유는input
값을 외부에서도 수정해주기 위해서이다.- ❗
onChange
함수는 변화를 감지하고 데이터를 업데이트 시켜주기 위함이다.
이제 hours
부분도 수정해보자.
function App() {
const [minutes, setMinutes] = React.useState();
const onChange=(event)=>{
setMinutes(event.target.value);
};
return (
<div>
<h1 className="hi">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={minutes/60}
id="hours"
placeholder="Hours"
type="number"/>
</div>
</div>
);
flip function
state
값에 따라 input
을 enabled
할지, disabled
할지 결정할 수 있다.
flipped
의 default 값은 false이다.
flipped
상태라면 state에 있는 값 그대로 보여주기flipped
상태가 아니라면 단위 변환된 값 보여주기
false
인 경우: 분=>시 변환,hours
는disabled=true
value={flipped ? amount : Math.round(amount/60)}
true
인 경우: 시=>분 변환,minutes
는disabled=true
value={flipped ? amount * 60 : amount}
✨이처럼 React는 state를 바탕으로 UI를 변경할 수 있는 유용한 언어이다.
component
는 그 안에 또 다른 component
를 렌더링할 수 있다. function MinutesToHours() { ...
function App() {
return (
<div>
<h1>Super Converter</h1>
<MinutesToHours />
</div>
);
}
{}
안에는 javascript
를 작성할 수 있다.input이 있고, 그리고 변화가 일어나면 state를 업데이트 한다.