[React] React Basic - (8) 정리
2020. 4.12
React Basic - (8) 정리
Food 예제
다양한 객체 선언 방식
const Food = ({fav, some, array}) => {
return (
<div>
<h1>My Favorite food is {fav}</h1>
<h2>{`This is ${some? 'true' : 'false'}`}</h2>
</div>
);function Food(props) {
return (
<div>
<h1>My Favorite food is {props.fav}</h1>
<h2>This is {`${props.some? 'true' : 'false'}`}</h2>
</div>
);function Food({ fav, img }) {
return (
<div>
<h1>My Favorite food is {fav}</h1>
<img src={img} />
</div>
);
}map() 함수를 통해 배열을 다른 형태로 바꾸는 다양한 방식
- 새로운 배열 생성 => map 내부에 arrow function 선언
const foodList = foodILike.map(food => (
<Food fav={food.name} img={food.image} />
));- 새로운 배열 생성 => map 내부에 일반 function 선언
const foodList = foodILike.map(function(food) {
return <Food fav={food.name} img={food.image} />;
});- return 내부에 바로 작성 ⇒ arrow function 사용
return (
<div>
{foodILike.map((dish)=> (
<Food
fav={dish.name}
img={dish.image}
/>
))}
</div>
);
...- return 내부에 바로 작성 ⇒ 외부 Function 사용
return (
<div>
{foodILike.map(renderFood)}
</div>
);
...
function renderFood(dish) {
return <Food key={dish.id} name={dish.name} img={dish.image}/>;
// key는 객체의 prop으로 넣을 필요가 없다. 기본적으로 react 내부에서 사용하기 위한 것이기 때문
}{console.log(foodILike.map(renderFood))}
{/* ERROR: Each child in a list should have a unique "key" prop. */}
{/* => 리스트의 모든 요소들은 유일한 key property를 가지고 있어야 함.*/}
해결 방법 : 배열의 각 요소에 id값을 부여한다.전체 Code
import React from "react";
import PropTypes from "prop-types";
// 객체 선언 : 방법 1
/* const Food = ({fav, some, array}) => {
return (
<div>
<h1>My Favorite food is {fav}</h1>
<h2>{`This is ${some? 'true' : 'false'}`}</h2>
</div>
);
} */
// 객체 선언 : 방법 2
/* function Food(props) {
return (
<div>
<h1>My Favorite food is {props.fav}</h1>
<h2>This is {`${props.some? 'true' : 'false'}`}</h2>
</div>
);
} */
// 객체 선언 : 방법 3
function Food({ fav, img, rating }) {
return (
<div>
<h1>My Favorite food is {fav}</h1>
<h4>{rating}/5.0</h4>
<img src={img} />
</div>
);
}
Food.propTypes = {
/* 각 prop 요소가 가져야 하는 형태를 정의함
: PropTypes를 통해 각 prop의 형태 / 존재 여부를 체크할 수 있음 */
name: PropTypes.string.isRequired,
image: PropTypes.string.isRequired,
// => .isRequired 가 없으면 undefined도 가능
/* rating: PropTypes.string.isRequired
=> rating이 string이어야 함. but 위 배열에서는 rating이 숫자로 표시되어 있기 때문에 console에서 ERROR 발생 */
rating: PropTypes.number.isRequired
};
// return 안에 들어가는 {}는 모두 JSX임
const foodILike = [
{
id: 1,
name: "chicken",
image:
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2" +
"Fth%3Fid%3DOIP.mIpo5pgFWyhPe1Iin4I8yQHaFF%26pid%3DApi&f=1",
rating: 5
},
{
id: 2,
name: "pork belly",
image:
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2" +
"Fth%3Fid%3DOIP.UmVEcfZCr9vDfLdcnDyoLAHaFj%26pid%3DApi&f=1",
rating: 4
},
{
id: 3,
name: "milkshake",
image:
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2" +
"Fth%3Fid%3DOIP.szKYcXQeNsJiTp6ScAw2mwHaEw%26pid%3DApi&f=1",
rating: 3
},
{
id: 4,
name: "sushi",
image:
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2" +
"Fth%3Fid%3DOIP._1YtdtHAiKCeGlC1piszvgHaEv%26pid%3DApi&f=1",
rating: 4.5
}
];
function App() {
// map : 방법 1 (새로운 배열 생성 => map 내부에 arrow function 선언)
/* const foodList = foodILike.map(
(food) =>(
<Food
fav={food.name}
img={food.image}
/>
)
); */
// map : 방법 2 (새로운 배열 생성 => map 내부에 일반 function 선언)
/* const foodList = foodILike.map(function(food) {
return (
<Food
fav={food.name}
img={food.image}
/>
)
}); */
return (
<div>
{/* map : 방법 3 (arrow function 사용) */}
{/* {foodILike.map((dish)=> (
<Food
fav={dish.name}
img={dish.image}
/>
))} */}
{/* map : 방법 4 (외부 Function 사용)*/}
{console.log(foodILike.map(renderFood))}
{/* ERROR: Each child in a list should have a unique "key" prop. */}
{/* => 리스트의 모든 요소들은 유일한 key property를 가지고 있어야 함.*/}
{foodILike.map(renderFood)}
</div>
);
}
function renderFood(dish) {
return (
<Food
key={dish.id}
name={dish.name}
img={dish.image}
rating={dish.rating}
/>
);
// key는 객체의 prop으로 넣을 필요가 없다. 기본적으로 react 내부에서 사용하기 위한 것이기 때문
}
export default App;State & Component Life Cycle
React Component
- Component에는 render(), state 등 많은 컴포넌트 요소들이 포함되어 있다.
- 'Component'를 extend 하면 react는 자동적으로 class Component의 render() 함수를 실행한다.
setState()
-
state의 속성
- state는 object이다.
- state에는 Component의 data를 넣을 수 있다.
- state는 변한다.
- state를 명시적으로 직접 변경해선 안된다. 대신, setState()를 사용해야 한다.
- 이유 : state는 객체이므로, 변경 시 원래 state 값에서 업데이트된 새로운 state 객체를 생성해야 한다.
- 매번 setState() 를 호출할 때마다 react는 새로운 state와 함께 render()를 호출한다.
- setState()를 통해 react는 rendering할 때 변화가 있는 부분만 감지하여 업데이트한다. ⇒ "Virtual DOM"의 특성
// 방법 1
this.setState({
count: this.state.count + 1
});
// => 권장하지 않는 방식.
// 방법 2
this.setState(current => ({
count: current.count++
}));
// react가 기본적으로 제공하는 current 변수 이용.render() 함수에서의 state 사용
// 방법 1
return <div>{this.state.isLoading ? "Loading" : "We are ready"}</div>;// 방법 2 => ES6
const { isLoading } = this.state;
return <div>{isLoading ? "Loading..." : "We are ready"}</div>;Component Life Cycle
-
Mounting : 컴포넌트가 생성되고 DOM에 입력될 때 호출되는 함수
- 호출 순서
- constructor()
- render()
- componentDidMount() : 컴포넌트가 처음 렌더링되었는지 알려줌
-
Update : state 등 컴포넌트가 변경될 때 호출되는 함수
- shouldComponentUpdate() : 조건이 true일 때만 컴포넌트를 업데이트하도록 정의
- render()
- componentDidUpdate() : 컴포넌트가 업데이트된 후(render() 함수가 호출된 후)에 호출됨.
-
Unmounting : 컴포넌트가 DOM에서 제거될 때 호출되는 함수
- componentWillUnmount() : 다른 페이지로 이동할 때, 페이지를 닫을 때와 같이 컴포넌트가 Unmount되기 직전에 호출됨.
setTimeout()
일정 시간 후에 state가 변하도록 설정
setTimeout(
() =>
this.setState({
isLoading: false
}),
3000
);
// 3초 후에 isLoading이 false로 변경됨.전체 Code
import React from "react";
class App extends React.Component {
state = {
count: 0
};
constructor(props) {
super(props);
console.log("constructor called");
}
add = () => {
this.setState(current => ({
count: current.count++
}));
};
minus = () => {
this.setState({
count: this.state.count - 1
});
};
render() {
console.log("I'm rendering");
return (
<div>
<h1>The number is {this.state.count}</h1>
<button onClick={this.add}>Add</button>
<button onClick={this.minus}>Minus</button>
</div>
);
}
componentDidMount() {
console.log("component rendered");
}
componentDidUpdate() {
console.log("I just updated");
}
}
export default App;