TIL # 35 (React intro 2)

41505 단어 ReactTILReact

1. JSX 공부하기

JSX element

HTML 문법을 JS 코드 내부에 써주기

const hi = <p>Hi</p>;

const myFavorite = {
  food: <li>샐러드</li>
  animal: <li>dog</li>,
  hobby: <li>programming</li>
};

JSX attribute

태그에 속성을 주고 싶을 때는 항상 ""로 감싸주기. class는 jsx에서 className이라 사용된다.

const hi = <input readOnly={true} />;

const myFavorite = {
    food: <li>샐러드</li>,
    animal: <li>dog</li>,
    hobby: <li className="list-item">programming</li>
};

Self-Closing Tag

JSX에서는 어떤 태그라도 self closing이 가능하다.

<input /> 그리고 <div /><div></div>는 같은 표현이다.

Nested JSX

1. 소괄호로 감싸기

const good = (
  <div>
    <p>hi</p>
  </div>
  };

2. 항상 하나의 태그로 시작

const right = (
<div>
    <p>list1</p>
    <p>list2</p>
</div>
);

Rendering

html 요소(element), React 요소 등의 코드를 눈으로 볼 수 있도록 그려지는 것. React 요소가 DOM node에 추가되어 화면에 렌더되려면 ReactDOM.render 함수를 사용한다. 첫 번째 인자에는 JSX로 React 요소를 인자로 넘기고, 두 번째 인자는 해당 요소를 렌더하고 싶은 container(부모요소)를 전달한다.

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root)
  );

2. Component 공부하기

컴포넌트는 재사용 가능한 UI 단위이다. 동일 코드가 반복되는 부분을 하나의 컴포넌트로 만들어서 같은 디자인의 input이 필요한 곳마다 재사용할 수 있다. 컴포넌트는 독립적으로 관리할 수 있으며 하나의 컴포넌트에 필요한 html, css, js를 모두 합쳐서 만들 수 있다. input을 받아서 return할 수도 있다. React 컴포넌트에서는 input을 props라고 하고 return은 화면에 보여져야할 React 요소가 return된다.

컴포넌트 만들기

React에서는 컴포넌트를 class나 함수로 만들 수 있다.

1. 함수로 Welcome 컴포넌트 구현하기

function Welcome(props) {
  return <h1>Hello, (props.name)</h1>;
}

2. class로 Welcome 컴포넌트 구하기
class로 컴포넌트를 만드려면 React.Component를 extend 해서 생성해야 한다. 생성할 때 무조건 render() 매서드를 정의해야 하고, return도 해주어야 한다.

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

컴포넌트 사용

위에 처럼 만든 컴포넌트는 함수 /class이름으로 사용할 수 있다.

<Welcome/>으로 작성하면 된다.

정의한 컴포넌트를 사용할 때, 원하는 attribute를 추가할 수 있고, 이것을 props라고 말한다.
.(dot)으로 속석명에 접근 가능하고, props.속성명으로 속성 값을 가져올 수 있다.

// 1. Welcome 컴포넌트 정의: 부모에서 name이라는 attribute를 부여함
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// 2. App 컴포넌트 정의: name이라는 attribute를 부여함
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
     </div>
    );
}

// 3. 화면에 React 요소 그려주기: root라는 id를 찾아 <App /> 컴포넌트 그려주기
ReactDOM.render(
  <App />,
  document.getElementById('root')
);

더 작은 컴포넌트로 분리하기

Comment라는 컴포넌트 내에 .avatar 요소컴포넌트로 만들기.

function Comment(props) {
  return (
    <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>
    );
}

.avatar 부분을 그대로 뗴와서 Avatar라는 이름으로 컴포넌트 만들어 준다. Comment 컴포넌트에서는 props.author로 접근해서 avatarUrl과 name을 가져왔는데, Avatar 컴포넌트에서는 좀 더 직관적으로 사용할 수 있도록 user 이름을 받아온다.

function Avatar(props) {
  return (
    <img className="avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
      />
    );
}

Avatar 컴포넌트에서 user의 avatarUrl과 name이 필요하므로, Comment 컴포넌트에서 props.author 정보를 user라는 attribute로 넘겨준다. props.author의 avatarUrl, name 값이 user를 통해 전달된다.

function Comment(props) {
  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>
    );
}

.user-info 부분을 그대로 떼어다가 UserInfo 라는 컴포넌트로 만들어 준다.

function UserInfo(props) {
  return (
    <div className="user-info">
      <Avatar user={props.user} />
      <div className="user-info-name">
        {props.user.name}
      </div>
     </div>
    );
}

Comment 컴포넌트가 아래처럼 확 간결해졌다 😙

function COmment(props) {
  return (
    <div className="comment">
      <UserInfo user={props.author} />
      <div className="comment-text">
        {props.tet}
      </div>
      <div className="comment-date">
        {formatDate(props.date)}
      </div>
     </div>
    );
}

3. Component의 State

State: 컴포넌트의 상태 값

state와 props는 둘 다 object이고, 화면에 보여줄 정보를 가지고 있다. props는 컴포넌트를 사용하는 부모쪽에 전달해야만 사용할 수 있고, state는 컴포넌트 내에서 정의하고 사용한다.

class Button extends React.Componet {
  
  constructor() {
    super();
    
    this.state = {
      clicked: false
    }
  }
  
  render() {
    return (
      <div
        className="btn"
        onClick={()=>{this.setState({ clicked: !this.state.clicked })}}
        >
        {this.state.clicked ? '좋아요' : '싫어요'}
      </div>
      );
  }
}

ReactDOM.render(
  <Button />,
  document.getElementById('root')

onClick={()=>{this.setState({ clicked: !this.state.clicked })}}

  • click하면 clicked 이라는 state를 수정합니다. this.setState() 함수로 state를 업데이트할 수 있다.
  • !this.state.clicked 으로 업데이트 한다는 말은, 현재 clicked 의 반대로(true면 false로, false면 true로) 저장한다.
  • onClick이 달려있는 <div />를 클릭할 때마다, clicked 상태가 true나, false로 업데이트 된다.

{this.state.clicked ? ‘좋아요’ : ‘싫어요’}

  • clicked state가 true면 ‘좋아요’ 를 보여주고 false면 ‘싫어요’를 보여준다.

constructor는 class의 instance가 생성될 때 항상 호출되는 함수(생성자)이다. 초기화할 값들을 constructor에서 세팅해준다. Button 컴포넌트를 그리려면 this.state.clicked 값이 필요한데, 제일 최초에는 값이 없으므로 constructor 에서 값을 지정해준다. super() 라는 키워드는 꼭 작성해야 React.Component class에 있는 메서드들(ex. render)을 사용할 수 있다.

Props와 state

앞에서 배웠던 props도 넣어보기. <Button />에 타입을 추가했고, Button 컴포넌트에서 props로 받을 수 있다.

class Button extends React.Component {
  
  constructor() {
    super();
    
    this.state = {
      clicked: false
    }
  }
  
  render() {
    return (
      <div
        className={`btn ${this.props.tyep === 'like' ? 'like-btn' : ''}`}
        onClick={()=>{this.setState({ clicked: !this.state.clicked })}}
        >
        {this.state.clicked ? '좋아요' : '싫어요'}
      </div>
      );
  }
}

ReactDOM.render(
  <Button type="like" />,
  document.getElemnetById('root')
);

좋은 웹페이지 즐겨찾기