어제 오늘 부트캠프 과제를 진행하면서 알게된 지식들을 끄적여본다.
그 이유는
규모가 큰 프로젝트일수록 컴포넌트 내부에 수많은 상태값들이 존재할 것이다. 만약 이 상태들의 값들이 제각각 변화할때마다 컴포넌트가 리렌더링된다면 성능 저하가 발생할 것이다.
이를 해결하기 위해서 리액트에서는 상태가 연속으로 변경되는 경우 배치(bach) 처리 를 통해 렌더링작업을 한번만 작동시켜 성능을 유지 한다.
배치는 리액트가 성능 향상을 위해 여러개의 상태(state)가 변화할 시 발생할 렌더링을 하나의 렌더링으로 묶어 한번만 렌더링하도록 하는 것을 의미한다.
범위는 16ms 으로 16ms 동안 변경된 상태 값들을 하나로 묶는다.
function App() {
const [inputValue, setinputValue]= useState('')
const onchange = (e) =>{
setinputValue(e.target.value)
console.log(inputValue)
}
return (
<div className="App">
<input type='text' onChange={(e)=>{
onchange(e)
}}></input>
</div>
);
}
input 태그에 onChange 이벤트를 부착해 타이핑 시 상태로 저장해둔 값인 inputValue
가 setinputValue
에 의해 변화하고 변화된 값을 확인하기 위해 콘솔을 찍어 보았다.
하지만 콘솔이 한템포 늦게 처리되는 것 처럼 보인다.
그 이유가 바로 useState 가 비동기적으로 처리되기 때문이다.!
비동기적으로 움직이기때문에
onchange()
함수가 호출되면 내부의setinputValue()
함수가 호출되고 실행이 다 끝나길 기다리지 않고 바로 다음 코드인 콘솔이 실행되어 한템포 늦게 처리되는 것 처럼 보이는 것!
setinputValue()
는 상태 변경 함수로 비동기적으로 처리되니 처리가 끝나길 기다리지 않고 밑에 코드를 실행
useState 를 동기적으로 사용하기 위해선 두가지 방법이 있다.
useEffect
를 사용하는 것setState
의 인자로 함수를 집어넣는 것useEffect
로 동기적 처리 구현하기function App() {
const [inputValue, setinputValue]= useState('')
// useEffect 추가!! 🔥
useEffect(()=>{
console.log(inputValue) // 여기서 콘솔 찍기!
},[inputValue]) // inputValue 상태가 변화할때마다 리렌더링!
const onchange = (e) =>{
setinputValue(e.target.value)
}
return (
<div className="App">
<input type='text' onChange={(e)=>{
onchange(e)
}}></input>
</div>
);
}
useEffect
안에서 inputValue
를 콘솔로 찍어보니 밀리는 현상이 없어졌다..!
setState
의 인자로 함수를 집어넣어 동기적 처리 구현하기onClick 이벤트와 달리 onChange 이벤트의 경우에는 어떤 함수를 인자로 넣어주어야 하는지 잘 모르겠다...😂
setState
내 함수의 매개변수로 이전 상태가 들어온다고 는 하는데 ,,,
setinputValue( (str)=> ,,,,)
여기서 setState 의 내부 함수의 매개변(str) 이 이전상태의 inputValue
가 될 것이고 이걸 바꿔야 하는거 같은데 아직 잘 모르겠다,,🥲
setState
란
상태를 변경시키는 함수! 위의 코드에선setinputValue
가setState
이다!
useState
는 비동기적으로 동작하는 Hook 이다.- 비동기적으로 동작하는 이유는 성능 최적화 때문임!
- 성능 최적화를 위해 배치(batch)를 사용한다.
useEffect
나setState
인자로 함수를 집어넣으면 동기적 처리가 가능하다.!
이벤트 버블링이란 한 요소에 이벤트가 발생하면, 이 요소에 할당된 이벤트 핸들러가 동작하고, 그 요소의 부모 요소의 핸들러도 동작하고 ,,, 가장 최상단에 위치한 요소까지 가면서 요소에 핸들러가 있다면 작동되는 현상을 말한다.
예를들어
<div onclick="alert('div에 할당한 핸들러!')"> <em><code>EM</code>을 클릭했는데도 <code>DIV</code>에 할당한 핸들러가 동작합니다.</em> </div>
이벤트핸들러가
<div>
에 할당되어 있지만,<em>
이나<code>
같은 중첩 태그를 클릭해도 동작한다.
버블링효과가 일어나지 않는 이벤트도 있긴하다! (일부 이벤트만 거의 대부분 버블링효과가 일어남)
해당요소의 이벤트 핸들러만 작동시키게 하기 위해선 버블링효과를 막아주어야 한다. 이럴때 사용하는 메서드가 있다.
event.stopPropagation()
이 메서드를 사용하면 버블링 효과를 중단시킬 수 있다..!
부모요소- 자식요소 둘다 핸들러가 부착되어 있는 경우에서 자식요소만 핸들러를 동작하게 하고 싶으면
자식요소의 핸들러에다event.stopPropagation()
메소드를 사용하면 된다.!
event.stopPropagation()
은 위쪽으로 일어나는 버블링은 막아주지만, 다른 핸들러들이 동작하는 건 막지 못한다.
모든 핸들러의 동작을 막기위해선 event.stopImmediatePropagation()
메서드를 사용하면 요소에 할당된 특정 이벤트를 처리하는 핸들러가 모두 동작하지 않게된다..! 👍🏻
배열을 Math.min()
Math.max()
를 통해서 최대 최소값을 구할려면 배열을 풀어서 괄호안에 넣어야한다.
이런경우 유용한 방법 두가지.!
let arr =[1,2,3,4,5]
Math.max(...arr) // 5
Math.min(...arr) // 1
apply( ) 메서드는 함수를 호출하는 메서드이다.
인자로는 두가지 인자를 가진다.
- 첫번째 인자 : 함수를 호출하는데 제공될 this 값
- 두번째 인자 : 함수를 호출할때 인수로 전달할 배열
let arr =[1,2,3,4,5]
Math.max.apply(null,arr) // 5
Math.min.apply(null,arr) // 1
첫번째 인자 this 예제
var obj = {
string: 'zero',
yell: function() {
alert(this<.string);
}
};
var obj2 = {
string: 'what?'
};
obj.yell(); // 'zero';
obj.yell.apply(obj2); // 'what?'
마지막 줄에 obj.yell.call(obj2)
로 this가 가리키는 것을 obj
에서 obj2
로 바꾸었다.
yell은 obj의 메소드인데도 this 가 참조하는 것이 zero 가 아니라 what?이 참조되었다.
즉 다른 객체의 함수를 자기 것마냥 사용할 수 있는 것이다..!