React 2 - Component와 Props
// function formatDate(date) {
// return date;
// }
// function Avatar(props) {
// return (
// <img className="avatar"
// src={props.user.avatarUrl}
// alt={props.user.name}
// />
// );
// }
// function UserInfo(props) {
// return (
// <div className="user-info">
// <Avatar user={props.user} />
// <div className="user-info-name">
// {props.user.name}
// </div>
// </div>
// );
// }
// function Comment(props) {
// return (
// <div className="comment">
// <UserInfo user={props.author} />
// {props.author}
// <div className="comment-text">
// {props.text}
// </div>
// <div className="comment-date">
// {formatDate(props.date)}
// </div>
// </div>
// );
// }
// function App() {
// return (
// <div>
// <Comment
// author="김개발"
// text="하이요"
// date="2019-10-28"
// />
// <Comment
// author="jasmine"
// text="스트레스받지말고"
// date="2020-08-31"
// />
// </div>
// )
// }
// ReactDOM.render(
// <App />,
// document.getElementById('root')
// );
// // 1. 전체 댓글창 컴포넌트 생성
// function Comment(props) {
// return (
// // comment 전체 부분
// // className=user-info -> 사용자 정보 : 사용자 이미지, 사용자 이름
// // className=comment-text -> 댓글 내용
// // className=comment-date -> 댓글 입력 날짜
// <div className="comment">
// <div className="user-info">
// <img className="avatar"
// src={props.author.avatarUrl}
// alt={props.author.name}
// />
// <div className="user-info-name">
// {props.author.name}
// </div>
// </div>
// <div className="comment-text">
// {props.text}
// </div>
// <div className="comment-date">
// {formatDate(props.date)}
// </div>
// </div>
// );
// }
// // 2. 더 작은 component로 쪼개보기
// // className avatar 태그 분리 후 Comment component 수정
// function Comment(props) {
// // Avatar component에서 user의 avatarUrl, name가 필요하므로
// // props.author 정보를 user라는 attribute로 넘겨주기 <Avatar user={props.author} />
// return (
// <div className="comment">
// <div className="user-info">
// <Avatar user={props.author} />
// <div className="user-info-name">
// {props.author.name}
// </div>
// </div>
// <div className="comment-text">
// {props.text}
// </div>
// <div className="comment-date">
// {formatDate(props.date)}
// </div>
// </div>
// );
// }
// // className avatar 태그를 Avatar 이름으로 component 로 만들기
// function Avatar(props) {
// // 직관적인 접근을 위해 user라는 이름 받아오기
// // user을 author 정보를 받아왔으니 객체에서 값을 추출하는 방법을 사용해서 원하는 정보를 추출해낸다
// // src={props.user.avatarUrl} 은 props.author.avatarUrl
// // alt={props.user.name} 은 props.author.name
// return (
// <img className="avatar"
// src={props.user.avatarUrl}
// alt={props.user.name}
// />
// );
// }
// 3. 한번더 분리해보기
function Comment(props) {
// className user-info component 만들기
// UserInfo component attribute에 user={props.author} 주기
// 2번에서 className user-info 독립전에 Avatar component에 user attribute의 정보를 전달해야되니
// UserInfo commponet 에 user={props.author} attribute 속성 주기
return (
<div className="comment">
<UserInfo user={props.author} />
<div className="comment-text">
{props.text}
</div>
<div className="comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
// 기존에 만든 Avatar component
function Avatar(props) {
return (
<img className="avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
// className user-info 태그를 UserInfo component 만들기
function UserInfo(props) {
return (
<div className="user-info">
<Avatar user={props.author} />
<div className="user-info-name">
{props.author.name}
</div>
</div>
);
}
function App() {
return (
<div>
<Comment
author="김개발"
text="하이요"
date="2019-10-28"
/>
<Comment
author="jasmine"
text="스트레스받지말고"
date="2020-08-31"
/>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
React 3 - Component의 State
// Button class component 생성
class Button extends React.Component {
// 생성자 생성 , super(); 필수
constructor() {
super();
// component 의 상태 정의
// click 은 false 로 할당
this.state = {
click: false
}
}
// 화면에 보여줄 render 함수 실행
// return 정의
render() {
return (
// className btn으로 onClick 이벤트 걸어주는데 따로 함수 생성하지 않고 바로 정의해도 된다
// arrow function 바로 정의
// 클릭 이벤트가 실행되면 setState로 click 의 상태를 반대로 바꾼다 (! 부정 연산자 사용)
// click 이 true 면 좋아요, false면 싫어요
// 버튼을 클릭할때마다 현재 상태의 값을 반전시키기 때문
// 기본값은 false 라서 만약 클릭을하면 true 로 바뀌는데
// {this.state.click ? '좋아요' : '싫어요'}에서 true 면 좋아요를 리턴하기 때문
<div
className="btn"
onClick={()=>{this.setState({ click: !this.state.click })}}
>
{this.state.click ? '좋아요' : '싫어요'}
</div>
);
}
}
ReactDOM.render(
<Button />,
document.getElementById('root')
);
class Button extends React.Component {
// class의 instance가 생성될때 항상 호출되는 함수 constructor
// 초기화할 값들을 세팅
// super(); 작성해야 React.Component 에 있는 메서드(render 등) 사용 가능, super은 부모 요소를 가져온다
constructor() {
super();
// component 의 상태 초기화
// 초깃값 false로 설정
this.state = {
clicked: false
}
}
// jsx를 화면에 보이기위한 render 함수 실행
render() {
// className 을 부모 요소의 type에 따라 결정 (props 객체에 있는 값을 가져온다)
// 부모 요소에 정의한 type이 'like'와 같다면 'like-btn' 반환, 아니면 '' 반환
// class name에 따라서 css 속성이 달라짐
// onClick 이벤트 걸어서 clicked 상태 업데이트
// 버튼을 클릭히면 현재 상태의 'clicked' 값을 반전시킨다
// 초기 'clicked' 세팅값은 flase다
// 버튼을 클릭하면 onClick 이벤트가 일어나 현재 상태의 clicked 값을 반전시킨다
// 조기 세팅값이 false이니 clicked는 true 로 바뀐다
// clicked의 값이 true 면 좋아요를 화면에 렌더한다
return (
<div
className={`btn ${this.props.type === "like" ? 'like-btn' : ''}`}
onClick={()=>{this.setState({ clicked: !this.state.clicked })}}
>
{this.state.clicked ? '좋아요' : '싫어요'}
</div>
);
}
}
// React 요소가 DOM node 에 추가되어 화면에 보여지려면 ReactDOM.render 함수 사용
// 첫번째 인자는 JSX로 React 요소를 인자로 넘기고
// 두번째 인자는 해당 요소를 보여주고 싶은 부모요소를 전달
ReactDOM.render(
<Button type="like" />,
document.getElementById('root')
);