Components need to “remember” things: the current input value, the current image, the shopping cart. In React, this kind of component-specific memory is called state.
export default function Gallery() {
let index = 0;
function handleClick() {
index = index + 1;
}
let sculpture = sculptureList[index];
return (
<>
<button onClick={handleClick}>
Next
</button>
<h2>
<i>{sculpture.name} </i>
by {sculpture.artist}
</h2>
<h3>
({index + 1} of {sculptureList.length})
</h3>
<img
src={sculpture.url}
alt={sculpture.alt}
/>
<p>
{sculpture.description}
</p>
</>
);
}
위의 코드의 handleClick 함수는 우리가 원하는대로 작동하지 않는다.
바닐라 자바스크립트로 웹에 동적인 기능을 추가하기 위해 우린 보통 variable와 함수를 이벤트리스너에 엮어서 코드를 작성한다.
리액트에서는 일반 자바스크립트 변수를 이용해서는 컴포넌트의 메모리 데이터값을 사용할수 없는 이유가 있는데 그이유로:
1. Local variables don’t persist between renders. When React renders this component a second time, it renders it from scratch—it doesn’t consider any changes to the local variables. - 로컬 변수는 리액트 랜더링 사이에서 에 지속되거나 유지되지 않는다. 리액트 엔진은 위 컴포넌트를 두번째 랜더링때 로컬 변수의 변화를 감지 못한다.
2. Changes to local variables won’t trigger renders. React doesn’t realize it needs to render the component again with the new data. - 일반 자바스크립트 변수로는 리액트를 랜더링을 트리거(작동을걸다) 시키지 못한다.
만약 우리가 리액트 컴포넌트를 업데이트 시키고 싶다고 한다면 두가지를 해야 하는데:
랜더링 사이에 컴포넌트 데이터 값을 유지할수 있어야 한다.
새로운 데이터값(i.e: 유저 이벤트, 인풋값 변화)으로 리액트 랜더링을 트리거 해야한다
그래서 우린 리액트에서 지원하는 useState 함수를 사용해 문제를 해결한다:
State variable to retain the data between renders- 상태 변수를 데이터 값을 랜더링 사이에서 유지한다.
State setter function to update the variable and trigger React to render the component again. - 상태 변수 setter 함수를 사용해 변수값을 업데이트 하여 리액트를 initial render후 다시 해당 컴포넌트를 랜더링 시킨다.
xport default function Gallery() {
const [index, setIndex] = useState(0);
function handleClick() {
setIndex(index + 1);
}
let sculpture = sculptureList[index];
return (
<>
<button onClick={handleClick}>
Next
</button>
<h2>
<i>{sculpture.name} </i>
by {sculpture.artist}
</h2>
<h3>
({index + 1} of {sculptureList.length})
</h3>
<img
src={sculpture.url}
alt={sculpture.alt}
/>
<p>
{sculpture.description}
</p>
</>
);
}
"use"Name- hooks는 리액트에서만 사용가능하며 컴포넌트 함수에서 toplevel에서만 사용 가능하면 커스텀 훅을 만들어 사용할수도 있다. Conditoinal, loops, 중첩 함수에서 사용할수 없다.
it’s helpful to think of them as unconditional declarations about your component’s needs. You “use” React features at the top of your component similar to how you “import” modules at the top of your file.
심플하게 덧붙이자면, useState를 사용해 리액트한테 뭔가를 "기억"하라고 한다.
한가지 공식문서의 팁을 빌리자면:
It is a good idea to have multiple state variables if their state is unrelated, like index and showMore in this example. But if you find that you often change two state variables together, it might be easier to combine them into one. For example, if you have a form with many fields, it’s more convenient to have a single state variable that holds an object than state variable per field. Read Choosing the State Structure for more tips.
The goal behind these principles is to make state easy to update without introducing mistakes.
State is isolated and private
State is local to a component instance on the screen. In other words, if you render the same component twice, each copy will have completely isolated state! Changing one of them will not affect the other.
State is not tied to a particular function call or a place in the code, but it’s “local” to the specific place on the screen. You rendered two components, so their state is stored separately.
Also notice how the Page component doesn’t “know” anything about the Gallery state or even whether it has any. Unlike props, state is fully private to the component declaring it.
Recap: