굉장히 중요!
리액트는 컴포넌트 기반.
모든 페이지가 컴포넌트로 구성되어 있고, 하나의 컴포넌트는 또 다른 여러 컴포넌트의 조합으로 구성될 수 있다.
a와 b로 표시된 부분이 리액트 컴포넌트
component-based라고 부르는 이유 : 작은 컴포넌트들이 모여서 하나의 컴포넌트를 구성. → 이러한 컴포넌트들이 모여서 전체 페이지를 구성.
하나의 컴포넌트를 반복적으로 사용함으로써 전체 코드의 양을 줄일 수 있음. → 개발 시간과 유지 보수 비용도 줄어듦.
리액트 컴포넌트의 입력은 Props
출력은 React element
: property(속성), component의 속성을 의미
컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체
같은 리액트 컴포넌트에서 색깔이나 속성을 바꾸고 싶을 때 사용하는 컴포넌트의 속재료.
같은 컴포넌트에서 생성되었지만 props가 다름.
: 값을 변경할 수 없다.
props 값은 컴포넌트가 element를 생성하기 위해 사용하는 값.
이 값들이 element가 생성되는데 바뀌게 된다면 제대로 된 element가 생성될 수 없을 것!(붕어빵 다 굽고 속재료 바꿀 수 없음 .. )
다른 props 값으로 element를 생성하려면?
→ 새로운 값을 컴포넌트에 전달하여 새로 element를 생성하면 됨.
이 과정에서 element가 다시 랜더링 되는 것.
//pure
function sum(a,b){
return a+b;
}
//impure 입력값을 변경.
function withdraw(account, amount){
acount.total -= amount;
}
Pure
입력을 변경하지 않으며, 같은 입력값에 대해허는 항상 같은 출력값을 리턴함.
모든 리액트 컴포넌트는 그들의 Props에 관해서는 Pure 함수 같은 역할을 해야한다.
⇒ 모든 리액트 컴포넌트는 Props를 직접 바꿀 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줄 것!
function App(props){
return (
<Profile
name="소품"
introduction="안녕하세요"
viewCount={1500}
/>
);
}
js 사용시 : 키와 값으로 이루어진 쌍의 형태로 컴포넌트에 props를 넣을 수 있음.
{} 사용 유무의 차이 : 문자열 이외에 정수 , 변수, 다른 컴포넌트 등이 들어갈 경우 {}를 사용해야 함. (문자열도 {}로 감싸도 됨.)
{
name="소품"
introduction="안녕하세요"
viewCount={1500}
}
props는 위와 같은 형태의 javascript 객체가 됨.
함수 컴포넌트를 개선해서 현재 많이 사용 중
함수 컴포넌트 개선하는 과정에서 개발된 것 → hook
간단한 코드가 장점.
function Welcome(props) {
return <h1>안녕, {props.name}</h1>;
}
class Welconme extends React.Componet {
render(){
return <h1>안녕, {this.props.name}</h1>;
}
}
React.component를 상속 받아서 welcome을 만듦.
React.component를 상속 받았기 때문에 리액트 컴포넌트가 되는 것.
컴포넌트의 이름은 항상 대문자로 시작해야 한다!
리액트는 소문자로 시작하는 컴포넌트를 DOM태그으로 인식하기 때문
컴포넌트로 만들어 낸 element 를 렌더링하면 됨.
Welcome 컴포넌트에 name=”인제”라는 값을 넣어서 호출하고 그 결과로 리액트 element가 생성 됨.
이 element는 리액트 돔을 통해서 실제 돔에 업데이트 되고
우리는 브라우저를 통해 볼 수 있게 된다.
컴포넌트 안에 또 다른 컴포넌트를 사용할 수 있다.
복잡한 화면을 여러 개의 컴포넌트로 나눠서 구현 가능
props를 사용해서 welcome 컴포넌트를 여러 번 사용함.
: 큰 컴포넌트에서 일부를 추출해서 새로운 컴포넌트를 만드는 것.
잘 활용할 시 컴포넌트의 재사용성이 올라감.
컴포넌트가 작아질수록 해당 컴포넌트의 기능과 목적이 명확해지고 props도 단순해지기 때문에 다른 곳에서 사용할 수 있는 가능성이 올라감
개발 속도 향상도 됨.
작성자의 프로필 이미지, 이름 , 댓글 내용, 작성일을 포함하고 있는 컴포넌트
위 컴포넌트의 props
function Avatar(props){
return <img className="avatar"
src={props.user.avartarurl}
alt={props.user.name}
/>
);
}
avatar 컴포넌트로 교체
function UserInfo(props) {
return (
<div className="user-info">
<Avatar user={props.user} />
<div className="user-info-name"/>
{props.user.name}
</div>
);
}
재사용이 가능한 컴포넌트를 많이 갖고 있을수독 개발속도가 빨라진다.
Comment.jsx
import React from "react";
const styles = {
wrapper: {
margin: 8,
padding: 8,
display: "flex",
flexDirection: "row",
border: "1px solid grey",
borderRadius: 16,
},
imageContainer: {},
image: {
width: 50,
height: 50,
borderRadius: 25,
},
contentContainer: {
marginLeft: 8,
display: "flex",
flexDirection: "column",
justifyContent: "center",
},
nameText: {
color: "black",
fontSize: 16,
fontWeight: "bold",
},
commnetText: {
color: "black",
fontSize: 16,
},
};
function Comment(props) {
return (
<div style={styles.wrapper}>
<div style={styles.imageContainer}>
<img
src="https://upload.wikimedia.org/wikipedia/en/b/b1/Portrait_placeholder.png"
style={styles.image}
/>
</div>
<div style={styles.contentContainer}>
<span style={styles.nameText}>{props.name}</span>
<span style={styles.commnetText}>{props.comment}</span>
</div>
</div>
);
}
export default Comment;
CommnetList.jsx
import React from "react";
import Comment from "./Comment";
const comments = [
{
name: "user1",
comment: "hello",
},
{
name: "user2",
comment: "hi",
},
{
name: "user3",
comment: "bye",
},
];
function CommentList(props) {
return (
<div>
{comments.map((commentList) => {
return (
<Comment name={commentList.name} comment={commentList.comment} />
);
})}
</div>
);
}
export default CommentList;
index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import CommentList from "./chapter_05/CommentList";
ReactDOM.render(
<React.StrictMode>
<CommentList />
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();