export default는 한번만 사용이 가능하고
export 변수는 많은것들이 export가 가능하다
//common.js
module.exports = a;
//es5 문법
export default a;
export const a;
두개는 호환이 된다고 생각하면 된다.
node의 문법을 common.js라고 부른다
.jsx에서 webpack을 사용하여서 import를 사용하면 되는데
webpack.config.js에서 import를 사용하면 호환이 되지않는다.
이 이유는 babel이 이 호환성을 만들어주기 때문
{['바나나', '포도', '사과', '딸기', '귤'].map( (v) => {
return (
<li>{v}</li>
);
})}
//바나나
//포도
//사과
//딸기
//귤
과같이 나타나게 된다.
javascript 의 Map함수를 사용하여서 React에 적용한 예제
고유한 key값을 가져와서 반복문안에 넣어야한다.
<li key={v.fruit + v.taste}><b>{v.fruit}</b> - {v.taste}</li>
map( (v, i) => {
return (
<li key={i}><b>{v.fruit}</b> - {v.taste}</li>
);
})
아래와 같이 i를 가지고 key를 만들어줄경우, react에서 key를 가지고 엘리먼트 추가하거나
수정 삭제시 판단을 하는데 배열의 순서가 바뀌면 문제가 생길수있다.
즉 이러한 방법을 가지고 사용을 해서는 안된다.
가독성, 성능최적화 등을 위해서 Component로 따로 빼게될때에
Data를 넘겨주기위해서 Props를 사용하게된다.
아래와같이 되어있으면 Try 컴포넌트에서는 v, i가 무엇인지 알지못하기 때문에
사용이 Try 컴포넌트에서 사용이 불가능하다.
{this.fruits.map( (v, i) => {
return (
<Try />
);
})}
{/* <input maxLength={4} value={this.state.value} onChange={this.onChangeInput} /> */}
React의 Render를 하는기준이 예전 state와 현재 state가 달라야 실행이되는데
만약 push만 그냥 해준다면, 그전의 state와 지금 state가 변경이된게 없다고 인식이된다.
그래서 React를 할때는 그냥 push만 하면안되고, 예전함수를 ...arr1로 넣어주고
그다음값을 넣어주어야한다.
ex)
this.setState({
result: '홈런!',
tries: [...this.state.tries, { try: this.state.value, result: '홈런!' }],
}); //...this.state.tries : 옛날것, { try: this.state.value, result: '홈런!' } : 추가할것
const { result, value, tries, answer } = this.state;
를 사용해서 this.state를 하나씩 다 안쓰고 위에 처럼 만들어줄수있다.
크롬에서 다운로드 받아서 사용
state, props가 변경되면 React가 불러오게되는데,
아래와 같이 state를 변경하지않고 그냥 setState만 변경하게되어도
render는 호출이 되게된다.
this.setState({});
원하는 render 조건을 해주는 방법.
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (this.state.counter !== nextState.counter) { //이전의 counter와 나중의 counter가 변경이될경우
return true; // render 한다
}
return false; // render 안한다
}
성능개선에 탁월!!!!!! [PureComponent, memo]
자식 컴포넌트에는 왠만해서는 넣어주는게 좋다. render가 될때 계속 리로딩되니 불필요한 Render가 되기때문
shouldComponentUpdate를 자동으로 구현해놓은것(PureComponent에서는 shouldComponentUpdate를 XX)
아래와 같이 PureComponent는 간단한 string,number, boolean 같은것들은 확인이 가능하나
object, array같은경우는 확인하기가 어렵다.
또한 array, object의 경우 일반적으로 그냥 push해서 직접넣어주면 render가 안되고
이전의 값들을 ...(전개연산자)로 넣어주고 다음원하는값을 넣어주어야만 이전값과의 비교가
되어서 render를 할수가있다.
** 또한 {[{}]} 이런식으로 너무 복잡하게는 state에 넣지는 말자.
state = {
counter: 0,
string: "hello",
number: 1,
boolean: true,
object: {},
array: [],
};
onClick = () => {
<!-- const array = this.state.array;
array.push(1);
this.setState({
array: array,
}); -->
this.setState({
array: [...this.state.array, 1]
})
};
Hooks에서는 아래와 같이 사용하게된다.
import React, { memo } from 'react';
// 구조분해 사용해서 props를 tryInfo로 바로 전환한후 사용
// Hooks를 사용할때에는 PureComponent도 없고, shouldComponentUpdate도 없기때문에 memo라는것을 사용 Props, state가 바꼈을때만 render
const Try = memo(({ tryInfo }) => {
return (
<li>
<div>{tryInfo.try}</div>
<div>{tryInfo.result}</div>
</li>
);
});
export default Try;
import React, { Component, createRef } from 'react';
inputRef = createRef();
<input ref={this.inputRef} maxLength={4} value={value} onChange={this.onChangeInput} />
A -> B -> C -> D -> E -> F -> G
이런식으로 나타날때에 중간 과정을 거치지 않고 A -> G로 곧바로 props나 데이터를 주고싶을때
Context를 사용, 또한 이러한 이류를 가지고 Redux도 사용이 가능하다
props -> context -> redux
Quiz
import React, {Component} from 'react';
class ResponseCheck extends Component {
state = {
state: 'waiting',
message: '클릭해서 시작하세요.',
result: [],
};
timeout;
startTime;
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초후에 settimeouts
} 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;
//삼항 연사자를 이용해서 if를 사용하기
return(
result.length === 0 ? null
: <>
<div>평균 시간 : {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={this.onReset}>리셋</button>
</>
)
};
render(){
return(
<>
<div id="screen" className={this.state.state} onClick={this.onClickScreen}>
{this.state.message}
</div>
{this.renderAverage()}
</>
)
}
}
export default ResponseCheck;