티스토리 뷰
구조분해 문법으로 적어줘야 깔끔해짐
render의 return안에서는 for과 if를 쓸 수 없음
JSX에서는 쓸 수 없음!
그래서 리액트 조건문은 삼항연산자로 많이 씀!
renderAverage = () => {
const { result } = this.state;
return result.length === 0
? null :
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
// 한번도 시도를 안했으면 태그가 없고:
// 시도를 한 순간부터 평균시간을 보여줌
};
JSX에서는 null, undefined은 태그가 없는 것으로 인식됨
// 삼항연산자 사용
const renderAverage = () => {
return result.length === 0
? null :
<>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={onReset}>Reset</button>
</>
}
return (
<>
<div id="screen"
className={state} onClick={onClickScreen}
>
{message}
</div>
{renderAverage()}
</>
)
굳이 if나 for을 쓰고 싶다면 {}안에 자바스크립트를 사용할 수 있는 원리를 사용해서 즉시 실행함수를 만들면 됨
> 그러나 코드가 지저분해져서 비추
// return 안에 if 사용
return (
<>
<div id="screen"
className={state} onClick={onClickScreen}
>
{message}
</div>
{(()=>{
if (result.length === 0) {
return null;
} else {
return <>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={onReset}>Reset</button>
</>
}
})()}
</>
)
for도 위와 같음
이런 경우는 자식 컴포넌트로 만들거나 함수로 빼는 것을 추천
+
반복문을 기점으로 자식 컴포넌트로 분리하기 좋음
불필요한 렌더가 발생하는 부분이 있는데
어쩔수없이 통째로 렌더가 다시 일어난다면 컴포넌트로 분리하는 것이 좋은 방법
반응속도 체크 만들기
// class
import React, { Component } from 'react';
class ResponseCheck extends Component {
state = {
state: 'waiting',
message: '클릭해서 시작하세요.',
result: [],
};
timeout; // 타임아웃 선언
startTime;
endTime;
onClickScreen = () => {
const { state, message, result } = this.state;
if (state === 'waiting') {
this.setState({
state: 'ready',
message: '초록색이 되면 클릭하세요.',
});
this.timeout = setTimeout(() => {
this.setState({
state: 'now',
message: '지금 클릭!',
})
this.startTime = new Date();
}, Math.floor(Math.random() * 1000) + 2000); // 2-3초 랜덤
} else if (state === 'ready') { // 성급하게 클릭
clearTimeout(this.timeout); // 타임아웃이 초기화가 안되고 계속 실행되므로 타임아웃도 초기화
this.setState({
state: 'waiting',
message: '너무 성급하셨습니다. 초록색이 되면 클릭하세요',
})
} else if (state === 'now') { // 반응속도 측정
this.endTime = new Date();
this.setState((prevState) => {
return {
state: 'waiting',
message: '초록색이 되면 클릭하세요.',
result: [...prevState.result, this.endTime - this.startTime], // 걸린 시간
}
})
}
};
onReset = () => {
this.setState({
result: [] // 결과를 초기화
})
}
renderAverage = () => {
const { result } = this.state;
return result.length === 0
? null :
<>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={this.onReset}>Reset</button>
</>
};
render() {
const { state, message } = this.state;
return (
<>
<div id="screen"
className={state} onClick={this.onClickScreen}
>
{message}
</div>
{this.renderAverage()}
</>
)
}
}
export default ResponseCheck;
useState와 useRef의 차이점
setState로 값을 바꾸면 return 부분이 다시 실행됨 > 렌더를 다시하게 됨
useRef로 값을 바꿔도 return이 다시 실행되지 않음 > 불필요한 렌더를 하지 않음
값이 바뀌어도 렌더링을 다시 시키고 싶지 않을 땐 useRef
또는 값이 바뀌기는 하지만 화면에 영향을 미치고 싶지 않을 때 useRef
예) timeOut, Interval 등이 주로 사용, 화면이 바뀌는건 원하지 않고 값은 바뀌는 것들 startTime, endTime
// hooks
import React, { useState, useRef } from 'react';
const ResponseCheck = () => {
const [state, setState] = useState('waiting');
const [message, setMessage] = useState('클릭해서 시작하세요.');
const [result, setResult] = useState([]);
const timeout = useRef(null);
const startTime = useRef();
const endTime = useRef();
const onClickScreen = () => {
if (state === 'waiting') {
setState('ready');
setMessage('초록색이 되면 클릭하세요.');
timeout.current = setTimeout(() => {
setState('now');
setMessage('지금 클릭!');
startTime.current = new Date();
}, Math.floor(Math.random() * 1000) + 2000);
} else if (state === 'ready') {
clearTimeout(timeout.current);
setState('waiting');
setMessage('너무 성급하셨습니다. 초록색이 되면 클릭하세요')
} else if (state === 'now') {
endTime.current = new Date();
setState('waiting');
setMessage('초록색이 되면 클릭하세요.');
setResult((prevResult) => {
return[...prevResult, endTime.current - startTime.current]
});
}
};
const onReset = () => {
setResult([]);
}
const renderAverage = () => {
return result.length === 0
? null :
<>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={onReset}>Reset</button>
</>
}
return (
<>
<div id="screen"
className={state} onClick={onClickScreen}
>
{message}
</div>
{renderAverage()}
</>
)
}
export default ResponseCheck;
Ref는 무조건 current로 접근하는 것 잊지말기
JSX는 배열 안에 넣어서 return하는 것도 가능, key값 필수
return [
<div key="사과">사과</div>
<div key="배">배</div>
<div key="바나나">바나나</div>
];
하지만 자주 사용하지는 않음
껍데기 태그를 더 많이 씀
return <>
<div key="사과">사과</div>
<div key="배">배</div>
<div key="바나나">바나나</div>
</>;
728x90
'유튜브 강의' 카테고리의 다른 글
제로초 리액트 강의 5.2 가위바위보 만들기 (0) | 2021.11.16 |
---|---|
제로초 리액트 강의 5.1 리액트 라이프 사이클, 고차 함수, useEffect (0) | 2021.11.16 |
제로초 리액트 강의 3.5 (0) | 2021.11.09 |
제로초 리액트 강의 3.4 리렌더링 방지, createRef (0) | 2021.11.09 |
제로초 리액트 강의 3.3 숫자야구 만들기 (0) | 2021.11.08 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Typescript
- vue
- javascript
- 타입스크립트
- 회고
- React
- TS
- Til
- 자바스크립트
- 제로초
- 코드잇
- CSS
- 저스트코드
- 코딩앙마
- 김버그
- js
- map
- 스파르타코딩클럽
- 깃
- 구름에듀
- 드림코딩
- 비주얼스튜디오코드
- 제이쿼리
- git
- 파이썬
- 리액트
- html
- Python
- scss
- vscode
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함