위코드-TIL-17-react-실습

jin_sk·2020년 6월 15일
0

위코드

목록 보기
38/49

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')
);

0개의 댓글