Binary Journey

[React][react-quickly review #1] 속성(props), 상태(state), 바벨(babel) 상태비저장 컴포넌트 관련 필기 본문

React

[React][react-quickly review #1] 속성(props), 상태(state), 바벨(babel) 상태비저장 컴포넌트 관련 필기

binaryJournalist 2020. 9. 28. 15:40
반응형

거창한 건 없고 주말에 <react-quickly>(리액트 교과서, 아자트 마르단 지음)에서 읽은 부분 잊지 않기 위해 필기한 부분만 저장하려고 한다.

 

react-quickly에서는 대략 3단계로 코드가 진행된다.

 

1. 일단 개념 소개용 코드

2. 1차 코드 리팩토링

3. 2차 코드 리팩토링

 

let helloWorldReactElement = <h1>Hello world!</h1>;

class HelloWorld extends React.Component {
  // 싱태비저장 컴포넌트
  render() {
    // return (
    //   <div>
    //     {helloWorldReactElement}
    //     {helloWorldReactElement}
    //   </div>
    // );
    // return React.createElement(
    //   "h1",
    //   this.props,
    //   `Hello ${this.props.frameworkName} world!!!`
    // );
    return <h1 {...this.props}>Hello {this.props.frameworkName} world!!!</h1>;
    // {...this.props} 이용하면 모든 속성 자식 엘리먼트로 전달 가능
  }
}

const HelloWorld = (props) => {
  // 상태비저장 컴포넌트를 위한 더 간결한 문법 제공
  return <h1 {...props}>Hello {props.frameworkName} world!!!</h1>;
};

// 상태가 필요하지 않다면 함수로 선언(상태비저장 컴포넌트를 생성하려면 함수로 선언하라는 것)
// (state 없이 render 함수만을 가짐,
// 확장하는 클래스를 정의하는 대신 props를 입력받아서 렌더링할 대상을 반환하는 함수를 작성할 수 있음)
// 상태 비저장 컴포넌트 함수 예제
function Link(props) {
  // 상태 비저장 컴포넌트
  return (
    <a href={props.href} target="_blank" className="btn btn-primary">
      {props.text}
    </a>
  );
}

const Link = props => (
  <a href={props.href} target="_blank" className="btn btn-primary">
    {props.text}
  </a>
);
const Link = (props) => {
  return (
    <a href={props.href} target="_blank" className="btn btn-primary">
      {props.text}
    </a>
  );
};

ReactDOM.render(
  <Link
    text="Buy React Quickly"
    href="https://www.manning.com/books/react-quickly"
  />,
  document.getElementById("root")
);


// 상태 비저장 컴포넌트는 상태를 가질 수 없음
// (propTypes와 defaultProps를 프로퍼티로 가질 수 있음, 컴포넌트 객체에 추가 가능)

 function Link(props) {
   return (
     <a href={props.href} target="_blank" className="btn btn-primary">
       {props.text}
     </a>
   );
 }
 Link.propTypes = {};
 Link.defaultProps = {};

// 상태 비저장 컴포넌트(함수)에서는 엘리먼트 참조(refs 불가능)

class DateTimeNow extends React.Component {
  render() {
    let dateTimeNow = new Date().toLocaleString();
    // return React.createElement('span', null, `Current date and time is ${dateTimeNow}.`);
    return <span>Current date and time is {dateTimeNow}.</span>;
  }
}

class ProfileLink extends React.Component {
  render() {
    return (
      <a href={this.props.url} title={this.props.label} target="_blank">
        Profile
      </a>
    );
  }
}

 

 

 

* Babel 명령줄 인터페이스 도구

* Node.js 브라우저 자바스크립트로 작성한 스크립트(API 방식), 패키지를 이용해서 스크립트를 작성하여 JSX 변환

* 빌드 도구: Grunt, Gulp, Webpack Babel 플러그인

* React팀도 자체 JSX 변화도구 개발을 중단하고 Babel 사용 권장함

 

* Babel, webpack을 이용하여 환경세팅하는 방법이 궁금해서 추가로 프로젝트를 만들어보았다.

-참고

https://medium.com/wasd/%EC%9B%B9%ED%8C%A9-webpack-%EA%B3%BC-%EB%B0%94%EB%B2%A8-babel-%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-react-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0-fb87d0027766

 

Webpack과 Babel을 이용한 React 개발 환경 구성하기

웹팩 설정 파일을 직접 작성하고 React 예제를 만들어보겠습니다.

medium.com

 

 

- 위의 글 내용 따라 만들어본 webpack.config.js

 

 

const HtmlWebpackPlugin = require("html-webpack-plugin");

const port = process.env.PORT || 3000;

module.exports = {
  // 개발환경
  mode: "development",

  // 애플리케이션 시작 경로, 애플리케이션 진입점을 나타냄
  entry: "./src/index.js",

  // 번들된 파일 경로, [hash]는 애플리케이션이 컴파일될 때 웹팩에서 생성된 해시를 사용함
  output: {
    filename: "bundle.[hash].js",
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/, // .js와 함게 .jxs 확장자도 같이 번들함
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },

      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
            options: {
              minimize: true, // 코드 최적화 옵션
            },
          },
        ],
      },
    ],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: "public/index.html",
    }),
  ],

  // 개발 서버 설정
  devServer: {
    host: "localhost",
    port: port,
    open: true, // open page when start
  },
};

 

 

 

- index.js에선 style 부분만 react-quickly를 보고 따라해보았다.

 

 

// index.js

import React from "react";

let smallFontSize = { fontSize: "10pt" };

const App = () => (
  <div>
    Hello, Webpack!
    <span>{[<span key="specialChars">&copy;&mdash;&ldquo;</span>]}</span>
    <br />
    <li object-id="097F4E4F">...</li>
    <br />
    <input style={smallFontSize} />
    <br />
    <input style={{ fontSize: "30pt" }} />
    <br />
    <span style={{ borderColor: "red", borderWidth: 1, borderStyle: "solid" }}>
      Hey
    </span>
    <br />
    <span style={{ border: "1px red solid" }}>Hey</span>
    <br />
    <input className="hidden" disabled={true} />
    <br />
    <input disabled />
  </div>
);

export default App;

 

 

 

 

[react-quickly 보고 파일에 직접 필기해놨던 부분 추가]

* 속성(props)

 - 속성을 변경하여 뷰를 갱신할 수 있으나 컴포넌트 내부에서 수정할 수 없음

 - 속성은 해당 컴포넌트 생성시에 전달받는 값이기 때문

 - 속성은 현재 컴포넌트에서 변경할 수 없으므로 부모 컴포넌트에서 컴포넌트를 새로 생성해서 새로운 값을 전달하는 방법 외에 컴포넌트의 속성을 변경할 수 없음

 - 뷰를 변경하기 위해서는 컴포넌트 내부에 변경할 수 있는 다른 자료형이 필요함

 

 * 상태 객체에 접근할 때는 이름 이용

 - 이름은 this.state 객체의 속성 (!= 컴포넌트 속성)

 - this.state.name

 

 * 상태 객체(this.state)와 속성(this.props)은 모두 클래스의 멤버

 - 상태 객체는 변경 가능

 - 속성은 변경 불가능

 - 속성은 부모 컴포넌트에서 전달하지만

 - - 속성 값을 변경하는 것은 오직 부모 컴포넌트에서만 가능, 자체적으로 변경 불가능

 - - 뷰 생성시에 정해짐, 정적인 상태로 유지

 

 - 상태는 부모 컴포넌트가 이는 해당 컴포넌트 자체에서 정의함

 - - 해당 컴포넌트에서 설정되고 갱신됨

 

 * 상태비저장 컴포넌트는 상태 객체가 없으며 컴포넌트 메서드 또는 다른 React의 라이프사이클 이벤트 또는 메서드를 갖지 않음

 * 상태비저장 컴포넌트의 목적은 오직 뷰를 렌더링하는 것

 * 상태비저장 컴포넌트는 예측할 수 있다는 이점이 있는데 출력을 결정하는 입력이 한 가지뿐이기 때문

 * 상태비저장 컴포넌트는 더 많이 사용할수록, 상태저장 컴포넌트는 더 적게 사용할수록 좋다

 

 

* 배열 push() 함수와 같이 더 익숙한 방식과 달리 concat() 함수는 기존 배열을 변경하지 않기 때문에 이를 더 권장

 

 

반응형