[리액트] 주요 개념

Wendy·2021년 8월 12일
0

학습기록

목록 보기
13/20

개요

리액트를 대충 말고 잘 알고싶다
그래서 리액트 공식문서를 차근차근히 읽어보고 궁금한건 테스트해보기로 했다.
아래에는 문서의 모든 내용이 아니라
새롭게 알게된것, 기억하고싶은것 등등만을 적으려고 한다.

시작하기 - 웹 사이트에 React 추가하기

리액트 프로그램을 엄청 거창하게 생각하고있었는데,
심플할 수 있다는걸 알게되었다..

CRA(create-react-app)로 생성하거나,
패키지화 해서 웹팩, 바벨 등등 환경구성 쫙 하고 이런것만 리액트가 아니라,
이렇게 일부에 간단하게 넣는것도 가능하구나~

레거시 코드에 조금씩 리액트를 추가해나가는게 어떻게 가능한지 이제 이해가 간다.

작은 리액트 프로그램 만들어보기

아래와 같이 index.html, ReactButton.js 두개의 파일로 리액트 프로그램을 만들수있었다!
1) 이렇게 작게도 가능하다니~
2) html사이에 일부만 적용하는게 이런 느낌이구나~


CRA에서는?

CRA를 통해 생성한 프로젝트를 빌드했을때도
요렇게 index.html에 id지정하고, 빌드된 파일을 script로 넣어주는 구조는 동일하다.

2. JSX 소개

JSX를 괄호로 묶어야 하는가?


필수는 아니지만, 이 작업을 수행할 때 자동 세미콜론 삽입을 피하고자 괄호로 묶는 것을 권장합니다 라고 되어있다. 그동안 묶어야 하는지 말아야 하는지 고민했었는데 여기 딱 기준이 있었네? 만약 return 케이스였다면 아래처럼 되어서 JSX가 리턴되지 못했을것이다. (물론 eslint등에서 괄호로 자동으로 묶어주기는 하지만 그런 장치가 없을경우...)

return 
  <h1> ... </h1>;
=> 
return ;
  <h1>...</h1>;

또한 자동 세미콜론 삽입에 대한 규칙이 따로 있다는 것도 처음 알았다.

camelCase

리액트에서 카멜케이스를 쓰는건 알고있었지만 이유를 생각해보지는 않았는데
HTML보다 JS에 가깝기 때문이라고 적혀있었다.

빈 요소를 갖는 태그는 닫아줘야한다

태그가 비어있다면 XML처럼 />를 이용해 바로 닫아주어야 합니다 라고 명시되어있다

얼마전에 .html파일에서 script태그는
<script src="" />처럼 쓰면 에러가 나고
<script src=""></script> 처럼 열고 닫기를 해야한다는걸 공부하면서

1) <... /> 로 쓸수있는 태그는 빈요소를 갖는 태그들이며
2) 이 경우 XML과 달리, /는 사실 가독성을 위한 선택사항이라는걸 배웠는데 (즉 태그를 열기만 하고 실제로는 닫지 않음)

JSX에서는 XML처럼 닫아주어야 한다고 명시가 되어있다!

실제로 테스트해보니
같은 프로젝트에서도 .html과 .js(.jsx)파일에서 오류여부가 달랐다

JSX는 주입 공격을 방지한다

태그 사이에 들어가는 children은 자동 escape가 된다고 명시되어있다.
하지만 props로 넣는것, dangerouslySetInnerHTML 를 통해 넣는것은 따로 처리를 해주어야 한다.

const text = "...자바스크립트가 동작할지도 모르는 뭔가 위험한 텍스트...";

//이건 안전 (자동 escape 적용)
return <h1>{text}</h1>;

//이건 위험 (자동 escape 없음)
return <a href={text}>Click</a>;
return <div dangerouslySetInnerHTML={{__html: text}}></div>;

JSX는 객체를 표현한다

React.createElement(태그, 속성, children)
읽기목록 추가 ㅜㅜ

3. Element 렌더링

4. Component와 Props

컴포넌트 이름은 항상 대문자로 시작해야 한다

React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리합니다.
만약 소문자로 시작하는 컴포넌트를 사용해야 한다면, 대문자로 시작하는 변수에 할당한 뒤 JSX에서 이 변수를 사용하세요.
코딩 컨벤션 정도로 생각하고 따라왔는데 이런 이유때문에 안된다는걸 처음 알았다.

const Hello = () => <div>Hello~~~</div>;
const bye = () => <div>bye~~~</div>;
const seeYouAgaine = () => <div>see you again~~~</div>;

function App() {
  const SeeYouAgaine = ()=>seeYouAgaine();
  return (
    <div className="App">
        <Hello />		//출력 성공 - 대문자 시작
        <bye />			//출력 실패 - 소문자 시작
        <SeeYouAgaine />	//출력 성공 - 소문자 함수를 대문자 변수에 할당
    </div>
  );
}

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

props를 수정하지 않아야 한다는건 알고있었는데,
항상 동일한 입력값에 대해 동일한 결과를 반환하는 순수함수처럼 동작해야 한다고 생각하지는 않았었던 것 같다.

5. State와 생명주기

setState

hook스타일을 주로 사용하다보니 setState에 대해서 잘 몰랐는데
useState와 비슷한듯 다르다.
callback함수를 전달할수있었다는게 신기..

setstate(nextState [, callbackFn]);
또는
setstate((state, props)=> {} [, callbackFn]);

6. 이벤트 처리하기

react에서 전달해주는 event는 합성 이벤트

브라우저 호환 걱정 없이 알아서 처리해준다고 한다

7. 조건부 렌더링

false로 평가될 수 있는 표현식 반환

const count = 0;
...
<div style={{backgroundColor:'yellow', color:'red'}}>
  1: {count && <h1>{count}</h1>}	//1:0
  <br />	
  2: {!!count && <h1>{count}</h1>}	//2:
</div>

false로 평가될 수 있는 표현식을 반환하면 && 뒤에 있는 표현식은 건더뛰지만 false로 평가될 수 있는 표현식이 반환 된다는걸 평소에 잘 생각하지 못했는데, 앞으로도 더 의미를 확실히 하게 하기 위해 !! 를 꼭 써주어야겠다.

컴포넌트가 렌더링하는 것을 막기

가끔 다른 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있을 수 있습니다. 이때는 렌더링 결과를 출력하는 대신 null을 반환하면 해결할 수 있습니다.

지금까지 이럴때는 <></> 를 전달했었는데, 공식문서에서는 null을 반환하라고 가이드가 있었네...?

8.리스트와 key

만약 리스트 항목에 명시적으로 key를 지정하지 않으면 React는 기본적으로 인덱스를 key로 사용합니다.

에러가 나니까 항상 고쳤는데, 알아서 이렇게 동작하고있는지 몰랐다

index를 key로 사용할 경우 부정적인 영향

//A, B, C 가 있고 추가를 클릭하면 D가 가장 앞에 추가됨
 {list.map(({name}, index) => (
   <div key={index}>
     <span>{name+" "}</span>
     <input type="text" defaultValue={'디폴트: '+ name} />
     <input type="text" value={'값: '+ name} />
   </div>
 ))}

index를 key로 사용하는데 배열의 추가/삭제가 발생하는 경우는
위와같이 상태값이 꼬일수있다...

9. 폼

제어되는 input null값

제어 컴포넌트에 value prop을 지정하면 의도하지 않는 한 사용자가 변경할 수 없습니다. value를 설정했는데 여전히 수정할 수 있다면 실수로 value를 undefined나 null로 설정했을 수 있습니다.

<input type="text" value='value' />	//input창에서 수정불가
<input type="text" value={null} />	//input 창에서 수정 가능

10. State 끌어올리기

11. 합성 vs 상속

12. React로 생각하기

가장 쉬운 방법은 데이터 모델을 가지고 UI를 렌더링은 되지만 아무 동작도 없는 버전을 만들어보는 것입니다. 이처럼 과정을 나누는 것이 좋은데 정적 버전을 만드는 것은 생각은 적게 필요하지만 타이핑은 많이 필요로 하고, 상호작용을 만드는 것은 생각은 많이 해야 하지만 타이핑은 적게 필요로 하기 때문입니다.

정적 버전을 만들기 위해 state를 사용하지 마세요. state는 오직 상호작용을 위해, 즉 시간이 지남에 따라 데이터가 바뀌는 것에 사용합니다. 우리는 앱의 정적 버전을 만들고 있기 때문에 지금은 필요하지 않습니다.

가끔 과하게 state를 사용하게 되는 경우가 있는데, 이런 방식으로 작성한다면 최소한의 state를 유지하는데 도움이 될 것 같다

궁금....

React, ReactDOM은 왜 파일을 나눠서 가져와야하지? 둘다 리액트 사용에 필수면 그냥 한 파일로 합치지 않은 이유가 있나?

React는 컴포넌트를 만드는 라이브러리. ex) Class ABC extends React.Component...
ReactDOM은 React를 DOM에 출력하기 위한 라이브러리. ex) ReactDOM.render(...);
내가 웹만 하다보니 생긴 궁금증이었다.
웹이 아니라 모바일을 한다면 React, ReactNative를 쓰면 된다.

읽기목록

JSX는 객체를 표현한다

읽어보고 싶었는데 스터디 일정이 빠듯해서 일단 적어만 둠 ㅜㅜ
React.createElement : https://medium.com/react-native-seoul/react-리액트를-처음부터-배워보자-02-react-createelement와-react-component-그리고-reactdom-render의-동작-원리-41bf8c6d3764
React 렌더링과 성능 : https://meetup.toast.com/posts/110
UI런타임으로서의 React : https://overreacted.io/ko/react-as-a-ui-runtime/

profile
개발 공부중!

0개의 댓글