[React/Basic/Component/State] React의 State
React는 Component로 이루어져 있다.
React는 JSX 문법을 이용해서 ,다양한 HTML 태그들을 가지게 되었습니다. 그리고 , 그 Element(HTML태그)들의 모아 놓은걸 하나의 컴포넌트라고 합니다. React에서는 이 Component가 1개의 최소 단위이며, 기능적인 단위입니다.
쉽게 생각하면, return문이 있는 JS 모듈 한 개라고 생각하면 됩니다.
React Component의 데이터 관리
React의 장점 중 하나인, 실시간 렌더링은 이벤트 루프와 같은 비동기 함수들과 함께 썼을 때 문제가 발생합니다. 이벤트는 "비동기"이므로, 이벤트가 실행이 되었을 때, 다시 딱 렌더링을 해줘야 했습니다. 즉 , 이벤트 발생시 마다 또 Render함수를 일일이 적어넣어줘야 했고, 그 반복적인 과정이 불편했습니다.
예를 들어 보겠습니다. like 버튼을 누르면, like의 수가 1이 늘어나는 간단한 기능을 만들어 보겠습니다. 우선, 전역 변수로 like를 두고, clickEvent가 발생할 때 마다, handleLike에서 like를 1 늘려주겠습니다.
<script type="text/babel">
const App = () =>{
let like = 0;
const handleLike = () =>{
like +=1;
console.log(like);
}
return(
<>
<span>{like}</span>
<button onClick={handleLike}>Like</button>
</>
)
}
ReactDOM.createRoot(root).render(<App/>);
</script>
다행히, 여기서는 누르면 의도한 대로 like값은 증가하지만, 새롭게 Render하는 부분이 없어 화면에는 나타나지 않습니다.
즉, 새롭게 Render하는 부분을 계속적어줘야 했습니다. 따라서, 데이터와 화면을 일치시키자는 좋은 방법으로 , React 에서는 State라는 새로운 개념을 제시하게 됩니다.
React의 State
State는 React에 동적인 데이터를 관리할 필요성이 생겼을 때, 사용하는 일반 JS 객체이고 state가 변하면 해당 Component는 rerendering됩니다. 즉, Data를 바꿨을 때, Render를 다시 해주는걸 자동으로 해주는 객체라고 생각하면 쉬울것 같습니다.
See the Pen simpleSearching(React) by Doge (@DogeIsFree) on CodePen.
React의 SideEffect
React의 State는 변화하는 동적인 값입니다. 근데, 이 State가 변할 때 마다, 어떠한 동작을 주고싶을 수 있습니다.
예를들어, 로그인 상태 state가 변했을 때, 해당 로그인 정보를 localStorage에 저장할 수 도 있고 , "새로고침을 눌러도 작성하던 글(state)들이 날아가지 않도록 만들고 싶다"면, Cookie, LocalStorage,Session 등 브라우저의 저장소를 이용하는 방법이 있을겁니다.
저는 위의 코드에서 like버튼을 눌렀을 때, 그 like된 정보를 저장해보도록 하겠습니다. 왜냐하면, SNS를 종료했다고 제 like 버튼이 다 날라가면 안되니까요.
엇, 그런데 이상한 문제가 발생했습니다. 분명히 LocalStorage에는 click한 순간에는 "true"가 들어가야하고, click을 한번 더 하면 false가 들어가야 합니다. 그치만, 결과는 달랐습니다.
See the Pen usingEffect(React) by Doge (@DogeIsFree) on CodePen.
* 원인
setIsLiked는 비동기 함수이기 때문에, LocalStorage에 적는 시점과 setIsLiked가 설정되는 시점을 다를 수 있습니다.
즉, State가 변경이 됬을 때, 어떠한 효과를 주기 위해서는 ,또 다른 방법이 필요하다는 거였죠. React에서 준비한 방법이 useEffect를 이용하는 방법입니다.
React의 useEffect
다시한번 , React에서 특정 state가 바뀌었을 때만 , 어떤 Effect를 발생시키고 싶을 때 사용하게 됩니다. 특정 state는 dependency배열에 넣고, 해당 배열의 값을 기준으로 판단하게 됩니다.
See the Pen usingEffect(React) by Doge (@DogeIsFree) on CodePen.
React의 Custom Hook
제가 짠 예제는 , State가 서로 Coupling이 되어 있어서, 사실 적합한 예제는 아닌것 같습니다.
하지만, 지금 State가 여러개가 있는데 각각의 State마다 다 LocalStorage에 저장하는 코드를 짠다면, 반복해서 짜는것 보다는 Hook들 또한, "함수화" 시켜서 짜는게 좋을겁니다.
React의 Custom Hook은 "Hook"들을 함수화 시키는 겁니다.
See the Pen Untitled by Doge (@DogeIsFree) on CodePen.
=== 해맸던곳 ==
* 로컬 스토리지에는 모든 값이 문자열로 저장이 됩니다. 따라서, getItem(props)==="true"라는 조건을 줘야합니다! 이것 때문에, 엄청 해맸습니다.. 흨흨
* JS에서는 return (조건)이 오면, 조건이 참이면 true, 아니면 false를 반환합니다. 다른언어에서도 지원하는지는 모르겠습니다. 논리연산자를 응용해서, (조건1) || (조건2)가 있다면, 조건 1이 true면 조건 1, 아니라면 조건 2가 반환되는 형태로 만들 수 있습니다.