렌더링 : 화면에 그려지는 것 리렌더링 : 화면에 다시 그려지는 것
리렌더링의 조건
1. 컴포넌트의 상태 변경
2. props의 변화
3. 부모컴포넌트가 리렌더링 되었을 때
상태를 만들어줘야 함.
useState를 통해 만듬
const [result, setResult] = useState(0);
return (
<View style={styles.container}>
<Text style={{ fontSize: 60 }}>{result}</Text>
<Button
title="+"
onPress={() => {
setResult(result + 1);
console.log(result);
}}
buttonStyle={{ width: 100, height: 100, marginBottom: 10 }}
buttonType={ButtonTypes.OPERATOR}
/>
<Button
title="-"
onPress={() => {
setResult(result - 1);
console.log(result);
}}
buttonStyle={{ width: 100, height: 100, marginBottom: 10 }}
buttonType={ButtonTypes.OPERATOR}
/>
<StatusBar style="auto" />
</View>
);
위에서 result가 state이고 (useState를 통해 선언) state는 setResult를 통해서만 바뀔 수 있다.
그렇게 되면 리렌더링이 되어 화면에도 반영되는 것을 확인할 수 있다.
마찬가지로 props에서도 state로 두면 리렌더링이 적용된다.
useState 에 대하여
비동기적으로 변형된다는 것을 알아야한다.
<Button
onPress={() => {
setResult(result + 1);
setResult(result + 1);
console.log(result);
}}
></Button>
위와 같이 코딩하였다면
2씩 증가하여야할 것 같으나 그렇게 되지 않는다 왜냐면 setResult는 비동기로 동작하기 때문에
첫번째가 완료되지 않았을 때 result 값은 변화되지 않은채로 두번째 코드가 동작하여 바뀌는 것을 알 수 있다.
이를 위해서는 setResult 안에서 함수를 호출하면 된다.
<Button
title="+"
onPress={() => {
setResult(prev => {
console.log('1 setREsult: ', prev);
return prev + 1;
});
setResult(prev => {
console.log('2 setREsult: ', prev);
return prev + 1;
});
}}
buttonStyle={{ width: 100, height: 100, marginBottom: 10 }}
buttonType={ButtonTypes.OPERATOR}
/>
반드시 함수형 업데이트를 진행할 것 그러면 비동기여도 그 전 코드를 반영하고 동작함을 볼 수 있다.
useState는 함수나 if문 등의 안에서 사용할 수 없다.
왜냐면 리렌더링 때문임
Hook1 Hook2 Hook3 Hook4
위의 Hook들을 기억하고 있다가 함수나 if문안에 있다면 조건에 따라 호출될 수도있고 안될 수도 있다.