리액트의 렌더링은 hooks 기준으로 setState만 호출 됐을 때 실질적인 state가 변경되지 않았을 경우에도 렌더링 되는 것을 확인할 수 있다.
따라서 그러한 것을 막기위해 shouldComponentUpdate에서 지정해줄 필요가 있다.
shouldComponentUpdate(nextProps, nextState, nextContext){
if(this.state.counter !== nextState.counter){
return true;
}
return false;
}
이렇게 하지 않고 간단하게 PureComponent를 사용하는 방법이 있다.
import React, {PureComponent} from 'react'
class Try extends PureCompnent {}
hooks기준이라면 memo를 사용한다.
import React, {memo} from 'react';
// class Try extends PureComponent {
// render(){
// const {tryInfo} = this.props;
// return(
// <li>
// <div>{tryInfo.try}</div>
// <div>{tryInfo.result}</div>
// </li>
// );
// }
// }
const Try = memo( ({tryInfo}) => {
return(
<li>
<div>{tryInfo.try}</div>
<div>{tryInfo.result}</div>
</li>
);
});
export default Try;
class에서 hooks처럼 ref 사용하는 방법
import {createRef} from 'react';
inputRef = createRef();
input ref={inputRef}
사용 시 this.inputRef.current.focus(); 가능
props와 state 연결하기
자식이 props를 변경하게 되면 부모의 props도 변경해야 한다. 자식이 부모를 바뀐다는 것은 문제가 되기 때문에 꼭 바꿔야 하는 경우 자식이 물려받은 props를 state로 만든다.
const Try = memo( ({ tryInfo }) => {
// tryInfo.try = 'gell' 안된다 props는 부모가 변경해야한다. 바꿔야할경우 state에 넣어준다. 좋은구조는아니지만
const {result, setResult} = useState(tryInfo.result);
const onClick = () => {
setResult('1');
}
return(
<>
<li>
<div>{tryInfo.try}</div>
<div onClick={onclick}>{tryInfo.result}</div>
</li>
</>
);
});
props의 자세한 설정이나, 이전 state를 받아 조정을 해 야하거나 , 즉 미세한 컨트롤을 위해 함수를 사용할 수 있다.
context : a -> b -> c ->d 컴포넌트가 존재할 경우 a에서 c로 보내고 싶을 경우 a ->b ->c로 넘겨야 한다.
즉 context를 응용한 것을 redux이다.
false , undefined, null은 jsx에서 태그 없음을 의미합니다.
import React, {Component} from 'react';
class ResponseCheck extends Component {
state = {
state : 'waiting',
message : '클릭해서 시작하세요',
}
render(){
return(
<>
<div
id="screen"
className={this.state.state}
onClick={this.onClickScreen}
>
{this.state.message}
</div>
{this.state.result.length === 0 ? null
:
<div>
평균시간 : {this.state.result.reduce( (a,c) => a + b ) / this.state.result.length}
</div>
}
</>
);
}
}
export default ResponseCheck;
함수로 빼줄 수도 있다.
import React, {Component} from 'react';
class ResponseCheck extends Component {
state = {
state : 'waiting',
message : '클릭해서 시작하세요',
result : [],
}
renderAverage = () => {
const {result} =this.state;
return result.length === 0 ? null :<div>평균시간 : {this.state.result.reduce( (a,c) => a + b ) / this.state.result.length}</div>
};
render(){
const {state , message} =this.state;
return(
<>
<div
id="screen"
className={state}
onClick={this.onClickScreen}
>
{message}
</div>
{this.renderAverage()}
</>
);
}
}
export default ResponseCheck;
이렇게 함수로 빼는 것도 좋지만 새로운 컴포넌트로 넘겨주어도 됩니다.
함수 컴포넌트는 렌더링 될 경우 전체가 실행되기 때문에 반복적인 함수 호출이 일어날 수 있습니다. useMemo나 , useCallback을 사용해야 합니다. 그전에 useeffect를 먼저 배워야 합니다.
class -> hooks전환
const ResponseCheck = () => {
const [state , setState] = useState('waiting');
const [message , setMessage] = useState('클릭해서 시작하세요');
const [result , setResult] = useState([]);
const timeReset =useRef(null);
const startTime =useRef();
const endTime =useRef();
const onClickScreen = () => {
if (state === 'waiting') {
setState('ready');
setMessage('초록색이 되면 클릭하세요');
timeReset.current = setTimeout( () => {
setState('now');
setMessage('지금클릭하세요');
}, Math.floor(Math.random() * 1000) +2000);
startTime.current = new Date();
}else if (state === 'ready'){
clearTimeout(timeReset.current);
setState('now');
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}>리셋</button>
</>
};
return(
<>
<div
id="screen"
className={state}
onClick={onClickScreen}
>
{message}
</div>
{renderAverage()}
</>
);
};
class에서는 ref를 통해 dom에 접근할 때만 사용했지만 hooks에서는 this. 속성을 ref로 표현합니다.
useRef는 업데이트 시 렌더링이 되지 않는다.
화면을 바꾸고 싶지 않는데 값이 변하는 것들을 ref에 사용합니다.
'FrontEnd > React' 카테고리의 다른 글
useMemo 와 useCallback (0) | 2020.07.22 |
---|---|
리액트 라이프사이클 (0) | 2020.07.22 |
반복문 (0) | 2020.07.18 |
require, import (0) | 2020.07.18 |
babel preset env , plugins (0) | 2020.07.16 |
댓글