[0706]함배리(함께 배우는 리액트)_보충

장 창영·2021년 7월 7일
post-thumbnail

6. Handling Events

React element에서 Handling events는 DOM element에서 Handling events와 유사

syntax differences
React event는 소문자 < camelCase를 사용
JSX로 event handler는 문자열 < 함수로 전달

HTML
<button onclick="activateLasers()">
  Activate Lasers
</button>

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

React에서는 false를 return해도 default를 막을 수 없고, preventDefault를 호출해야 함
e는 synthetic(합성) event로, cross-browser compatibility(호환성) 있음

HTML
<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

React
function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

DOM element가 생성된 후 listener를 추가할 때 addEventListener를 호출할 필요없음
처음 element가 rendering될 때 listener를 제공

ES6 class를 사용해서 component를 정의할 때, 일반적인 패턴은 event class의 method로 evnet handler를 만듦

class className extends React.Component {
  constructor(props) {
    super(props);
    this.state = {key: value};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
  }

  render() {
    return (
      <button onClick={this.handleClick}>
      </button>
    );
  }
}

or

handleClick = () => {}
  
or

<button onClick={() => this.handleClick()}>

JSX callback 안에서 this에 주의. JavaScript에서 class method는 기본적으로 binding돼있지 않음. binding하지 않고 전달하면 this는 undefined됨 not React-specific < JavaScrip
not bind?
1. public class fields 문법 사용한다면, class fields를 사용하여 callback을 바인딩
2. callback에 화살표 함수 사용
rendering될 때마다 다른 콜백이 생성 -> callback이 하위 component에 props로 전달되면 component들은 추가로 re-rendering을 수행

6-1. Passing Arguments to Event Handlers

loop 내부에서 event handler에 추가적인 parameter를 전달

화살표
onClick={(e) => this.handleClick(id, e)}
바인드
onClick={this.handleClick(this, id)}

7. Conditional Rendering

React에서 원하는 동작을 캡슐화하는 component를 만들 수 있음
component 중에서 몇 개만 rendering할 수 있음

React에서 조건부 rendering은 JavaScript 조건처리처럼 동작
If나 조건부 연산자처럼 JavaScript 연산자를 현재에 맞는 element를 사용하면, React는 현재에 맞는 UI를 업데이트할 것.

function funcName(props) {
	const tf = true
  if (tf) {
    return <TrueFunc />;
  }
  return <FalseFunc />;
}

ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  <funcName tf={false} />,
  document.getElementById('root')
);

7-1. Element Variables

element를 저장하기 위해 변수 사용.
output의 다른 부분은 바꾸지 않으면서 component의 일부를 조건부로 rendering 가능

variable 선언 + if 사용
-> shorter syntex? JSX 안에서 inline으로 {포현식} 처리!

7-2. Inline If with Logical && Operator

&& 사용

  • true && expression = expression
  • false && expression = false

7-3 Inline If-Else with Conditional Operator

condition ? true : false 사용

7-4. Preventing Component from Rendering

다른 component에 의해 rendering될 때 component를 숨기고 싶을 경우, rendering 결과를 대신 null을 return
component runder로 null을 return하는 것은 component의 라이프사이클 method에 영향을 주지 않음
componentDidUpdate() 여전히 호출됨

8. Lists and Keys

8-1. Rendering Multiple Components

const list = numbers.map((parameter) =>
  <tag>{list}</tag>
);

map()으로 배열을 반복 실행

ReactDOM.render(
	<tag>{list}</tag>
    document.getElementById('root')
);

8-2. Basic List Component

component 안에서 리스트를 rendering?
key는 element 리스트를 만들 때 포함해야 하는 문자열 attribute

X
const list = numbers.map((parameter) =>
  <tag>{list}</tag>
);

O
const list = numbers.map((parameter) =>
  <tag key={parameter.toString()>{list}</tag>
);

8-3. Keys

Key는 React가 어떤 항목을 변경추가삭제할지 식별 시 사용
Key는 element에 안정적인 identity를 부여하기 위해 리스트 내부의 element에 지정

const list = numbers.map((parameter) =>
  <tag key={parameter.toString()>{list}</tag>
);

key는 uniquely identified string
주로 데이터의 ID를 key로 사용하지만, index도 가능
그러나 항목의 순서가 바뀔 수 있는 경우 key에 index를 사용하지 않는 걸 권장 -> 성능 저하 + state 문제 발생

8-4. Extracting Components with Keys

Key는 주변 배열의 context에서 의미를 가짐
보통 map() 내부의 element에 key를 넣는 것이 좋음

8-5. Keys Must Only Be Unique Among Siblings

Key는 siblings 사이에서만 unique하고 globally unique할 필요없음 = 다른 배열에 같은 key 사용가능
React에서 Key는 힌트를 제공하지만 component로 전달하진 않음 = Key와 동일한 값이 필요하면 다른 prop으로 전달

8-6. Embedding map() in JSX

{표현식} -> map()의 결과를 인라인으로 처리가능
변수 추출 vs 인라인 처리?

9. Forms

HTML form element는 form element 자체가 internal state를 가지기 때문에, React의 다른 DOM element와 다르게 작동
JavaScript function으로 form 제출을 처리하고 사용자가 form에 입력한 데이터에 접근하도록 하는 것이 편리함 -> “controlled components” 이용

9-1. Controlled Components

HTML에서는 form elements는 user input을 기반으로 state를 관리고
React에서는 mutable state가 component의 state 속성에 의해 유지되며 setState()에 의해 업데이트

React의 state를 신뢰 가능한 single source로 만들어 두 요소를 결합
form을 rendering하는 component는 user input을 제어 -> React에 의해 값이 제어되는 form element = controlled component

class FormName extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert(this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

controlled component로 사용하면, input 값은 항상 React state에 의해 결정
= 코드 더 써야댐 = 다른 UI element에 값을 전달 + 다른 event handler에서 값을 재설정 가능

9-2. The textarea Tag

HTML에서 textarea element는 텍스트를 children로 정의
React에서 textarea value attribute를 대신 사용 -> 한 줄 입력을 사용하는 폼과 비슷하게 작성
this.state.value는 constructor에서 초기화하므로, textarea는 일부 텍스트를 가진 채 시작

9-3. The select Tag

HTML에서는 select는 drop-down list를 만듦 + selected attribute로 option이 initially selected
React에서는 select tag에 value attribute를 이용 -> 한 곳에서 업데이트만 하면 되기 때문에 controlled component에서 사용하기 용이

mutiple={true} 허용 시, value attribute로 {[배열]} 전달 가능

9-4. file input tag

HTML에서 input type="file"은 사용자가 파일을 서버로 업로드 가능
React에서는 value가 read-only이기 때문에, uncontrolled component임

9-5. Handling Multiple Inputs

multiple controlled input element를 제어할 때, 각 element에 name attribute를 추가하고, event.target.name을 통해 작업을 선택

ES6 computed property name syntax
-> input 태그의 name에 일치하는 state를 update

this.setState({
  [name]: value
});

ES5 code
-> setState()는 현재 state에 일부 state를 merge함

var partialState = {};
partialState[name] = value;
this.setState(partialState);

9-6. Controlled Input Null Value

controlled component에 value prop을 지정하면 의도하지 않는 한 사용자가 변경할 수 없음
변경할 수 있음? = value를 undefined나 null로 설정했을 수 있음

9-7. Alternatives to Controlled Components

데이터 변경할 모든 방법에 대해 이벤트 핸들러 작성 + React component를 통해 모든 입력 상태를 연결 -> controlled component가 불편
기존 코드베이스를 React로 변경 or React가 아닌 라이브러리와 애플리케이션을 통합 -> 불편
uncontrolled component! (다음에)

9-8. Fully-Fledged Solutions

validation + keeping track of the visited fields + handling form submission
-> Formik! (요것도)

10. Lifting State Up

동일한 데이터에 대한 변경사항을 여러 component에 반영?
-> 가까운 공통 ancestor로 state를 lifting up!

10-1. Lifting State Up

React에서 해당 state를 필요로 하는 component 간의 common ancestor로 state를 'lifting state up'해서 state를 공유
shared state를 소유한 component는 “source of truth”이라고 부름

10-2. Lessons Learned

React 안에서 변하는 데이터에 대해서는 “source of truth”를 하나만 두어야 함
state는 rendering이 필요한 component에 먼저 추가됨
다른 component도 state가 필요하면 common ancestor로 state를 'lifting state up'하면 됨. 다른 컴포넌트 간에 state를 sync < top-down data flow 나음
Lifting state는 two-way binding approach보다 “boilerplate” code를 더 많이 포함하지만 버그를 찾고 격리하는 것에 유리
state는 component 안에 live하기 때문에, 자신의 state를 스스로 변경할 경우 버그가 줄어듦

11. Composition vs Inheritance

React는 강력한 composition(합성) 모델을 가짐
-> Inheritance < Composition을 추천
-> reuse code between components

11-1. Containment

어떤 component는 어떤 children element가 들어올지 모를 수 있음
ex) generic 'boxes' 역할을 하는 'sidebar', 'dialog' 등의 component

이런 component는 'children prop'을 사용하여 children element에 바로 그들의 output을 전달하는 게 좋음
ex) {props.children}

종종 component에 여러 "holes"가 필요할 수 있음
children 대신 자신의 고유한 방식을 적용할 수 있음

React element는 object이기 때문에 다른 데이터처럼 prop으로 전달가능 “slots”과 비슷하지만, prop은 제한이 없다는 매력in other

11-2. Specialization

어떤 component의 "special cases"인 component를 고려해야 하는 경우가 있음
-> composition을 통해 해결?
"specific"한 component가 "generic"한 component를 rendering하고 props를 통해 내용을 구성

Composition은 class로 정의된 component에서도 동일하게 적용

11-3. So What About Inheritance?

Props와 composition은 component의 모양과 동작을 커스터마이징하는 유연성을 제공
non-UI를 여러 component에서 reuse하기 원한다면 별도의 JS module로 분리하는 것이 좋음
상속 없이 component에서 해당 함수, 객체, 클래스를 import하여 사용할 수 있음

12. Thinking in React

React -> JS를 통한 big fast web

12-1. Start With A Mock

12-2. Step 1: Break The UI Into A Component Hierarchy

= component hierachy 만들기

Draw components, sumbcomponent -> mock component all names

어떤 것이 component가 될 수 있음? 함수나 객체처럼 하면 됨
'single responsibility principle'를 지키자!
-> component는 one thing만 하는 것이 이상적
component가 커지면 하위 component로 decompose해야 함

12-3. Step 2: Build A Static Version in React

= rendering UI + static version component 만들기
build component(reuse other components + pass data using props)
props o, parent -> child
state x, only for interactivity(change over time)

top-down or bottom-up? top-down

library of reusable components that render your data model
static version -> only have render() methods
최상단의 component (FilterableProductTable)는 prop으로 데이터 모델을 받음
데이터 모델이 변경 -> ReactDOM.render() 호출하여 UI가 업데이트
React의 one-way data flow(one-way binding)은 모든 걸 modular하고 fast하게 만듦

A Brief Interlude: Props vs State 중요

12-4. Step 3: Identify The Minimal (but complete) Representation Of UI State

= state를 통해 Interactive UI 만들기

최소한의 mutable state를 설정
-> DRY(Don’t Repeat Yourself)
1. 부모로부터 props를 통해 전달? state x
2. 시간이 지나도 안 변함? state x
3. component 안의 다른 state나 props를 가지고 계산가능? state x

12-5. Step 4: Identify Where Your State Should Live

= 어느 component가 state를 mutate하고 own할지 정하기

flowing down
component 어떤 state를 가져야하는지?
1. 해당 state를 기반으로 rendering하는 모든 component를 찾기
2. common owner component 찾기
common owner component? 계층 구조 내에 특정 state가 있어야 하는 모든 component의 상위에 있는 component
3. common + 상위 component가 state를 가져야 함
4. state를 소유할 적절한 component가 없다면, state를 소유할 component를 만들어서 common owner component의 상위 계층에 추가

12-6. Step 5: Add Inverse Data Flow

= state를 계층구조 최하단에서 업데이트

two-way data binding과 달리 data flow가 명시적으로 보이고 어떻게 프로그램이 동작하는지 파악할 수 있게 도와줌

12-7. And That’s It

explicitness와 modularity으로 component의 large libraries를 만드는 것에 좋을 듯

  • code reuse으로 코드 라인이 줄 듯 :)

0개의 댓글