이전 글인 React - 기초
의 처음으로 돌아가 보자.
<body>
<span id="counter">Total clicks : 0</span>
<button id ='btn'>Click me</button>
</body>
<script>
let counter = 0;
const button = document.querySelector('#btn')
const counterMsg = document.querySelector('#counter')
function hadnleClick(){
counter += 1;
counterMsg.innerText = `Total clicks : ${counter}`
}
button.addEventListener('click',hadnleClick)
</script>
</html>
버튼을 누르면 counter
가 늘어나는 코드가 있었다.
이 코드를 다시 React JSX(JavaScript XML) 문법으로 작성해 보자.
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = document.querySelector("#root")
// counter 생성
let counter = 0;
// 함수 생성
function countUp(){
counter += 1;
}
const Container = () => (<div>
// counter 변수를 집어넣음
<h3>Total clicks: {counter}</h3>
// tag에 이벤트 추가
<button onClick={countUp}>Click me</button>
</div>);
ReactDOM.render(<Container />, root);
</script>
</html>
{변수}를 사용하여 tag안에 직접 넣어서 활용
<h3>Total clicks: {counter}</h3>
이벤트 리스너도 tag의 attribute에 넣어주는 형식이다.
<button onClick={countUp}>Click me</button>
두개의 공통점은 대괄호{}를 사용한다는 것이다.
EventListener
의 경우에는 Tag 속성에 넣어준다.
차이점으로는 React
에서는 false
를 반환해도 기본 동작을 방지할 수 없습니다.
반드시 preventDefault
를 명시적으로 호출해야 한다.
예를 들어, 일반 HTML에서 폼을 제출할 때 가지고 있는 기본 동작을 방지하기 위해 다음과 같은 코드를 작성할 수 있습니다
출처 : reactjs
위에 코드는 console
에서는 작동하나 browser
에서는 작동하는게 보이지 않았다.
이유는 render가 되지 않았기 때문이다.
처음에 ReactDOM.render(<Container />, root);
가 최초 작동되고 그 뒤로는 작동하지 않았기 때문이다.
그렇다면 어떻게 해야 할까?
방법은 아주 간단하다 함수로 만들어 주면 끝!
//기존 코드 생략
function countUp(){
counter += 1;
render() // 함수 추가
}
function render(){ // 함수로 생성
ReactDOM.render(<Container />, root);
}
const Container = () => (<div>
<h3>Total clicks: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>);
render() // 함수 호출
render
라는 이름으로 함수를 만들어주고
countUp
에서 호출,그리고 원래 있었던 자리에 다시 호출해 준다.
이제 정상작동 하는것을 볼수있다.
눈에 보이는 차이점은 그렇게 크진 않지만, 코드를 작성할때에 편리함과 가독성이 좋아진 느낌이다.
더 명확하게 차이가 나는 것은 바로 이것이다.
span
태그가 업데이트가 되는게 눈에 잘 보인다.
UI
에서 바뀐 부분만 업데이트해 준다.
감싸고 있는 태그 전체를 업데이트 하지 않고 바뀌는 요소(component)만 업데이트 해주는 똑똑한 React
지금도 좋지만 코드가 늘어날 때마다 계속해서 render()
를 호출하는 상황이 올 것이다.
개선해 보도록 하자.
const data = React.useState(0);
console.log(data) // 출력 : (2) [0, ƒ]
return(<div>
useState()
에 0의 값을 주었더니 출력 값이 [0,f]
라는 결과가 나왔다.
여기서 알 수 있는 것은 첫번째 요소는 입력한 값이라는 것이다.
두번째 값은 그 값을 바꾸는 함수이다.
const food = ['banana','pineapple']
food[0] // 'banana'
food[1] // 'pineapple'
그렇다면 이련 형식으로 하면 된다. 그러나 이러면 늘어날수록 코드가 지저분해 진다.
const food = ['banana','pineapple']
const ['first','seconds'] = food
first // 'banana'
seconds // 'pineapple'
배열안에 변수를 만들어 재정의 하여 사용할 수 있다.
<script>
function App() {
const [counter,setCounter] = React.useState(0);
const onClick = ()=>{
setCounter(counter+1);
}
return (
<div>
<h3>Total clicks :{counter}</h3>
<button onClick={onClick}>click me</button>
</div>)
};
ReactDOM.render(<App />, root);
</script>
useState(0) = 초기값 0
setCounter(counter+1); = 바꿔줄 함수
rerender 더 깔끔한 코드가 완성되었다...
이렇게 보면 js보다는 확실히 깔끔해서 좋은거 같다.
현재 state를 다음 state로 계산하려면 function을 사용하면 된다.
// setCounter(counter+1);
setCounter((current) => current +1);
}
React가 current라는 현재 값을 보장한다.
그래서 더 정확하고 더 안전하다.