React 개념서 내맛대로 요약

배채윤·2023년 2월 3일
0

1. Hello World!

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

2. JSX 소개

const element = <h1>Hello, World!</h1>;

Javascript를 확장한 문법.

React에서는 본질적으로 렌더링 로직이 UI로직(이벤트가 처리되는 방식, 시간에 따라 State가 변하는 방식, 화면에 표시하기 위해 데이터가 준비되는 방식 등)과 연결됨.

별도 파일에 마크업과 로직을 넣어 각각의 technologies를 인위적으로 분리하는 대신, 둘다 포함하는 "컴포넌트"라고 부르는 느슨하게 연결된 유닛으로 Cocern을 Separating한다.(컴퓨터 프로그램을 구별된 부분으로 분리시키는 디자인 원칙으로, 각 부문은 개개의 관심사를 해결한다. 관심사란 컴퓨터 프로그램 코드에 영향을 미치는 정보의 집합)

JSX에 표현식 포함하기

const name = 'Chaeyun';
const element = <h1>Hello, {name}</h1>;

중괄호 안에 모든 JS 표현식을 넣을 수 있음.

3. Rendering Element

엘리먼트는 컴포넌트의 '구성요소'

React로 구현된 앱은 일반적으로 하나의 Root DOM 노드가 있음
React 엘리먼트를 렌더링 하기 위해서는 우선 DOM 엘리먼트를 ReactDOM.createRoot()에 전달한 다음, React 엘리먼트를 root.render()에 전달해야 한다.

<div id="root"></div>
const root = ReactDOM.createRoot(
  document.getElementById('root')
);
const element = <h1>Hello, world</h1>;
root.render(element);

렌더링된 Element 업데이트하기

React 엘리먼트는 Immutable object임.
UI를 업데이트하는 방법은 새로운 엘리먼트를 생성하고 이를 root.render()로 전달하는 거임.
아래는 setInterval() 콜백을 이용해 초마가 root.render()를 호출하게 하는 로직.

const root = ReactDOM.createRoot(
  document.getElementById('root')
);

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);
}

setInterval(tick, 1000);

=> 매초 전체 UI를 다시 그리도록 만들었지만 React DOM은 내용이 변경된 텍스트 노드만 업데이트 시켜줌.

4. Components와 Props

React는 컴포넌트를 통해 UI를 여러 조각으로 나누고 재사용함.
개념적으로 JS 함수와 유사. props라는 임의의 입력을 받아 화면에 어떻게 표시할지 Element를 반환함.

함수 컴포넌트와 클래스 컴포넌트

  • 함수 컴포넌트
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
  • 클래스 컴포넌트
class Welcome extends React.Component {
  render() {
  	return <h1>Hello, {this.props.name}</h1>;
  }
}

Rendering Components

const root = ReactDOM.CreateRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;
root.render();

Composing Components

자신의 출력에 다른 컴포넌트를 참조할 수 있음. 즉, 모든 단계에서 동일한 추상 컴포넌트를 사용할 수 있음.
React에서는 Button, Form, Dialog, Screen 등의 것들이 흔히 컴포넌트로 표현됨.

function App() {
  return(
    <div>
      <Welcome name="Sara"/>
      <Welcome name="Chaeyun" />
    </div>
    );
}                    

props는 읽기전용

모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 한다.

5. State와 Lifecycle

State는 Props와 유사하지만 비공개이며 컴포넌트에 의해 완전히 제어함.

class Clock extends React.Component {
  constructor(props) {
    super(props); // 클래스 컴포넌트는 항상 props로 기본 constructor를 호출해야 함.
    this.state = {date: new Date()}
  }
  
  // Clock이 렌더링될 떄마다 타이머 설정
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000);
  }
  
  // Clock에 의해 생성된 DOM이 삭제될 때마다 타이머 해제
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  
  
  render() {
    return (
      <div>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
      );
  }
}
  
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);

State 올바르게 사용하기

  • 직접 State를 수정 X. setState() 사용하면 됨
    this.state를 지정할 수 있는 유일한 공간은 constructor
  • State 업데이트는 비동기적일 수도 있음.
  • State 업데이트는 병합된다.
    여러 독립적인 변수를 포합할 수 있고 별도 setState() 호출을 통해 이를 같은 state에 merge 할 수 있음.

The Data flows down

부모 컴포넌트나 자식 컴포넌트 모두 특정 컴포넌트가 유상태인지 또는 무상태인지 알 수 없고, 그들이 함수나 클래스로 정의되었는지에 대해서 관심을 가질 필요가 없음.

#top-down(하향식), #unidirectional(단방향식) 데이터 흐름. 모든 State는 항상 특정 컴포넌트가 소유하고 있으며 오직 아래에 있는 컴포넌트에만 영향을 미친다.

6. 이벤트 처리하기

  • React 이벤트는 소문자 대신 camelCase를 사용.
  • JSX를 사용하여 함수로 이벤트 핸들러 전달
  • false를 반환해도 기본 동작을 방지 X
// HTML
<button onclick="activateLasers()">
  Activate Lasers
</button>

// JSX
<button onClick={activateLasers}>
  Activate Lasers
</button>

이벤트 리스터 붙이기 예시

  • JS에서 클래스 메서드는 기본적으로 바인딩되어있지 않음.
    this.handleClick을 바인딩 하지 않고 onClick에 전달하면 함수가 실제로 홀출될 때 thisundefined됨.
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

이벤트 핸들러에 인자 전달하기

// 화살표 함수
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row></button>
// Function.prototype.bind -> 추가 인자(e)가 자동으로 전달됨
<button onClicnk={this.deleteRow.bind(thid, id)}>Delete Row</button>

7. 조건부 렌더링(Conditional Rendering)

  • 조건에 따른 컴포넌트 렌더링
function Greeing(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeing />;
 }

const root = ReactDOM.createRoot(document.getElementById('root')); 
// Try changing to isLoggedIn={true}:
root.render(<Greeting isLoggedIn={false} />);
  • 조건에 따라 컴포넌트 렌더링 X
function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<Page />);

8. List 와 Key

class NumberList extends React.Component {
  const numbers = props.numbers;
  
  render () {
    return (
    numbers.map((number) =>
                <li key={number.id}>
                   {number}
                </li>);
                );
      }
}

Key는 엘리먼트 리스트를 만들 떄 포함해야하는 특수 문자열 어트리뷰트.
React가 어떤 항목을 업데이트할지 식별하는 것을 도움.
안정적인 고유성을 위해 배열 내부 엘리먼트에 지정해야 함.
대부분 데이터의 ID로 key를 사용.
배열로 사용할 때만 의미 있음.
Key는 Siblings 사이에서만 고유하면 됨.

9. Form

제어 컴포넌트(Controlled Component)

React 에 의해 값이 제어되는 입력 폼 엘리먼트

HTML에서 input, textarea, select 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트함.
vs
React에서는 변경할 수 있는 state가 일반적으로 컴포넌트 state에 유지되며 setState()에 의해 업데이트 됨

// input
<input type="text" value={this.state.value} onChange={this.handleChange} />

// textarea
<textarea value={this.state.value} onChange={this.handleChange} />

// select
<select value={this.state.value} onChange={this.handleChange}>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
</select>

value 어트리뷰트는 폼 엘리먼트에 설정되므로 표시되는 값은 항상 this.state.value가 되고 React state는 신뢰 가능한 단일 출처 (single source of truth)가 된다.
값이 변하면 handleChange를 동작하게 하여 state를 바꿔줌

select 태그에서는 html의 selected 어트리뷰터를 사용하는 대신 value 를 사용.

profile
새로운 기술을 테스트하고 적용해보는 걸 좋아하는 서버 개발자

0개의 댓글