TIL 40 | React.js Intro

meow·2020년 8월 29일
1

React

목록 보기
1/33
post-thumbnail

React?

리액트는 페이스북의 UI를 더 잘 만들기 위해 페이스북에서 만든 JavaScript UI 라이브러리이다. 리액트의 컴퍼넌트는 가독성, 재사용성을 높여주고 유지보수를 쉽게 만들어준다. 효과적으로 웹 어플리케이션을 만들 수 있고, 나만의 컴퍼넌트를 만들고 남이 만든 수많은 컴퍼넌트를 사용할 수도 있다.

라이브러리

재사용이 필요한 기능으로 반복적인 코드 작성을 없애기 위해 언제든지 필요한 곳에서 호출하여 사용할 수 있도록 Class나 Function으로 만들어진 것이다. 사용 여부는 코드 작성자 선택사항이며 새로운 라이브러리 제작 시에도 엄격한 규칙이 존재하지 않는다. 제작 의도에 맞게 작성하면 된다. jQuery 역시 자바스크립트 라이브러리 중 하나이다.

JSX(JavaScript XML)

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

위 문법은 JS도, HTML도 아닌 JSX라고 불리는 JavaScript 확장버전이다. JavaScript 파일 내에서 작성할 수 있다. JSX는 원래의 JS 문법과 다르기 때문에 .js 파일 내에 JSX 문법이 있으면 브라우저에서 문법 오류가 발생한다. React.js를 사용하기 위해 JSX 문법이 포함되어 있으면, 해당 파일을 정규 JS 문법으로 변환시키는 컴파일 과정이 필요하다.

JSX element

HTML 문법을 JS 코드 내부에 써주면 그게 바로 JSX이다. .js 파일 어디에서나 필요한 곳에 작성하면 된다. 변수에 저장할 수도 있고, 함수의 인자로 넘길 수도 있다.

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

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

JSX attribute

태그에 attribute(속성)을 주고 싶을때는 항상 쌍따옴표 "" 로 감싸줘야 한다. attribute를 추가 하고싶을 때는 실제 HTML에서 쓰는 attribute name(속성명)과 다를 수 있다. 예를 들어, class를 주고 싶을 때 속성명은 class이지만, JSX에서는 className을 사용해야 한다.

Self-Closing Tag

JSX에서는 어떤 태그라도 self closing tag가 항상 가능하다. <input> 처럼 하나의 태그가 요소인 경우에는 <input />과 같이 항상 /로 끝내줘야 한다. <div /><div></div>는 같은 표현이다.

JSX 특징

  • 모든 요소를 감싸는 최상위 요소 (cf. React Fragments : <> ... </>)
  • 자바스크립트 표현 : { ... javascript... }
  • class vs. className
  • Inline Styling : <div style={{color : "red"}}>Hello React</div>
  • Self Closing tag : <div></div> vs. <div />

Nested JSX

  1. (필수) 소괄호로 감싸기
const good = (
  <div>
      <p>hi</p>
  </div>
);
  1. (필수) 항상 하나의 태그로 시작
const wrong = (
  <p>list1</p>
  <p>list2</p>
);

위와 같이 제일 처음 요소가 sibling이면 안되고 무조건 하나의 태그로 감싸져야 한다. 아래와 같이 첫 요소는 하나의 태그로 감싼다.

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

Rendering

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

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

Component

component란 재사용이 가능한 UI 단위이다. 동일 코드가 반복되는 부분을 하나의 component로 만들어서 같은 디자인의 요소가 필요할때마다 재사용이 가능하고, 하나의 디자인이 바뀌었을때 css 한줄만 수정하면 바뀐 디자인이 동일한 component가 적용된 모든 요소에 반영이 된다. 따라서 컴포넌트는 독립적으로, 재사용 가능한 코드로 관리할 수 있다. 하나의 컴포넌트에 필요한 HTML, css, JS를 모두 합쳐서 만들 수도 있다. ( 🤭 오.. )

이는 마치 독립적이고 재사용 가능한 함수와도 유사한 성질이다. 컴포넌트 역시 input을 받고 return도 할 수 있다. React 컴포넌트 에서는 input을 props라고 말하고, 화면에 보여져야 할 React요소가 return 된다.

Component 만들기

React는 컴포넌트를 만들고 관리하기 좋은 라이브러리이다. React에서는 컴포넌트를 경우에 따라 class나 함수로 만들 수 있다.

함수로 Welcome 컴포넌트 구현

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

class로 Welcome 컴포넌트 구현

class로 컴포넌트를 만드려면 React.Component를 extend해서 생성한다. 컴포넌트를 생성할 때 render() 메서드는 무조건 정의해야 하고, return도 해야한다. render() 메서드를 무조건 정의해야 한다는 말은, component를 만들 때 필요한 메서드가 원래 더 있다는 말이다. 그 중에서 render() 만이 필수이다.

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

Component 사용

정의한 컴포넌트는 함수 또는 class의 이름으로 사용할 수 있다. 태그와 같이 <Welcome />으로 작성한다. 우리가 정의한 컴포넌트를 사용할때는 원하는 attribute를 얼마든지 추가할 수 있다. 그러면 컴포넌트에서 parameter로 해당 attribute를 받아서 사용할 수 있다. 이것을 props라고 하고, 이는 property의 준말이다. .(dot)으로 속성명에 접근가능하고, props.속성명 으로 속성값을 가져올 수 있다.

// 1. Welcome 컴포넌트 정의
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// 2. App 컴포넌트 정의
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

// 3. 화면에 React 요소 그려주기
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
  1. Welcome 컴포넌트: Welcome 컴포넌트를 사용한 측(부모)에서 props.name 값을 사용한다.
  2. App 컴포넌트: div로 감싸져있고, <Welcome /> 컴포넌트를 세번 사용한다. name이라는 attribute를 부여해주었다.
  3. ReactDOM.render 함수로 React 요소를 그려준다. root라는 id를 찾아 <App /> 컴포넌트를 그려준다.

더 작은 Component로 분리하기

재사용할 가능성이 조금이라도 있으면 컴포넌트로 만들어주는 것이 좋다. 아래의 Comment라는 컴포넌트를 작은 Commponent로 쪼개보자.

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 컴포넌트는 댓글창 이외에도 사용자 정보 등 여기저기 많이 쓰일 것 같다. (인스타그램 댓글, 검색, 스토리, 팔로우 추천을 만들었던 것을 생각하면 쉽다.)

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

.avatar 부분을 그대로 떼어와서 Avatar라는 이름의 컴포넌트를 만들어준다. Comment 컴포넌트에서는 props.author로 접근해서 avataUrl과 name을 가져왔는데, Avatar 컴포넌트에서는 좀 더 직관적인 user 이름으로 받아온다. 이러한 경우 <Avatar />를 사용하는 측에서 user라는 attribute를 추가해야한다.

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

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

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

.user-info 부분을 컴포넌트 부분으로 만들어 한번 더 분리가 가능하다. 재사용 가능성이 1이라도 있으면 컴포넌트로 만들자!!! 💫💫💫

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

이렇게 확 간결해진 Comment 컴포넌트를 만들었다! 이해 안되면 두번, 세번, 네번 다시 읽자.

profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글