React, component, JSX, Hook, State, Props, 불변성
터미널에서 yarn으로 react 폴더를 생성해준다
yarn create react-app 폴더명
바탕화면에 지정한 폴더를 VSCode에 열어준다
VSCode에서 생성한 react 파일을 local로 연결해 준다
yarn start
localhost:3000으로 접속이 가능해 진다
새로고침을 하지 않아도 VSCode에서 수정해서 저장하면 바로 확인이 가능하다
(npm으로도 가능하다)
레고블럭과 같은 개념이다
필요한 블럭만 사서 조립을 할 수도 있고 패키지로 구매해서 조립을 할 수 있다
HTML태그를 리턴하는 함수를 만든다
function App() {
return <div></div> // HTML 태그 작성 부분
}
export, import로 여러 Component들을 이어준다
import App from "./App.js"
// component
export default App;
import는 윗쪽에 export는 아랫쪽에 입력한다
해당 파일들을 불러올 수 있다
JSX문법을 사용한다 이 부분은 밑에 따로 써야겠다
function App() {
// JavaScript 작성 부분
return (
<div>
{ // JSX 문법 작성 부분 }
// HTML 태그 작성 부분
</div>
)
}
JSX문법은 Babel로 자동으로 변형해준다
<input type="text" />
img처럼 닫는 태그가 없을 경우 /> 이렇게 닫아주어야 한다
function App() {
return (
<p></p> // 오류 발생
<div>
<h1></h1>
</div>
div태그 안에 한번에 묶어주어야 한다
function App() {
const name = 'chan'
return (
<div>
{name} // chan 화면에 표시됨
</div>
중괄호가 없을 경우에 HTML 태그로 인식하므로 꼭 중괄호안에 작성해야 한다
<div className="main">
<label htmlFor="name"></label>
</div>
JavaScript 문법에 class, for가 있기 때문에 적용해주려면 className, htmlFor로 기입해야 한다
<div style={{ color: "red" }}>
</div>
스타일을 직접 지정하려면 {{ }} 중괄호를 두개 써주어야 한다
component간의 정보를 교류할 때 사용한다
부모 component로부터 받아온 데이터이다
부모에서 자식으로만 사용할 수 있다
component에 parameter로 props를 넣어준다
function Mother () {
const name="chan"
return <Child motherName={name} />
}
function Child (props) {
console.log(props) // object가 출력된다
// object = { motherName: 'chan' }
return <div>{props.motherName}</div>
// chan이 화면에 렌더링 된다
}
Mother(부모) component에서 Child(자식) component로 props 데이터를 넘겨주었다
그래서 화면에 chan이 렌더링 된다
객체의 값에 접근하는 방법으로 작성을 해주면 화면에 출력할 수 있다
props.motherName
// chan 출력
function Child({ motherName }) {
return <div>{motherName}</div>
}
props drilling
Prop Drilling은 props를 오로지 하위 컴포넌트로 전달하는 용도로만 쓰이는 컴포넌트들을 거치면서 React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정입니다
propTypes 타입검사
자바스크립트의 유연한 특성 때문에 작성이 편한 반면 파일이 많아지면 생산성이 떨어진다는 점 때문에 타입스크립트를 많이 사용하는데 반드시 자바스크립트를 이용해 앱을 개발해야 하는 상황에서는 이러한 문제점을 피하기 위해 PropTypes를 활용하는 것을 권장한다
PropTypes는 부모로부터 전달받은 prop의 데이터 type을 검사한다 자식 컴포넌트에서 명시해 놓은 데이터 타입과 부모로부터 넘겨받은 데이터 타입이 일치하지 않으면 콘솔에 에러 경고문이 띄워진다
[참고문서] https://ko.reactjs.org/docs/typechecking-with-proptypes.html
function App() {
return <User>Hi!</User>
}
function User(props) {
return <div>{props.children}</div>
}
화면에 Hi! 가 출력된다
여러 component에 재사용할 때 유용하다
function Child(props) {
return <div>{props.name}</div>
}
Child.defaultProps = {
name: "default값"
}
name값이 없을 경우 default값이 지정되어 출력된다
parameter안에 직접적으로 입력하는 것도 가능하다
function Child({name = "default값"}) {
return <div>{name}</div>
}
component 내부에서 바뀔 수 있는 값을 의미한다
State를 사용하는 예시이다
import React, { useState } from "react";
const [value, setValue] = useState(초기값)
꼭 import를 해주어야 한다
import가 자동으로 작성되기도 하지만 안되서 오류나는 경우도 있으니 확인해야 한다
value는 state이름이고 setValue는 state를 변경할 때 사용하는 함수이다
setValue를 통해서만 state값을 변경할 수 있다
초기값은 initial State이다
말 그대로 초기값을 지정해 주는 것이다
📍 JavaScript 문법은 바뀔 수 있는 값은 const가 아니고 let으로 선언한다
하지만 여기서 let이 아니라 State를 사용하는 이유를 알아보아야 한다
component는 LifeCycle이라는 개념이 있고 LifeCycle에 따라 화면 값이 변했을 때
그 변화된 값을 화면에 다시 리렌더링 시켜주기 위한 조건들이 있다
그 중 하나가 State가 변경되었을 때이다
JavaScript에서 let으로 선언해서 그 값을 새로운 값에 할당시켜 줄 수는 있지만
React에 의하면 변경된 값이 화면에 바로 반영되지 않는다
State가 값이 변경되었다고 인식하지 못하기 때문이다
그렇기 때문에 변화를 감지하고 화면을 즉시 리렌더링 시켜주기 위해 State를 사용한다
function App () {
function onClickHandler () {
console.log('Click!')
}
return (
<div>
<button onClick={onClickHandler}>버튼</button>
</div>
)
}
함수와 component를 연결하는 것이다
onClick함수에 JavaScript에서는로 적용해주었지만
JSX문법에 따라 {} 중괄호 안에 괄호를 빼고 작성한다
function App () {
const [name, setName] = useState('chan')
function onClickHandler () {
setName('anna')
}
return (
<div>
<p>{name}</p>
<button onClick={onClickHandler}>변경하기</button>
</div>
)
}
State를 사용해서 초기값 'chan'을 button을 눌렀을 때 'anna'로 변경해준다
setName은 값을 변경할 때 사용한다
function App () {
const [value, setValue] = useState('');
function onChangeHandler (e) {
const inputValue = e.target.value // input에서 추출한 값
setValue(inputValue) // 추출한 값을 setValue에 연결시켜 준다
}
return (
<div>
<input type="text" onChange={onChangeHandler} value={value} />
</div>
}
}
input의 value값도 같이 지정해야 한다
onChangeHandler에 e.target.value는 JavaScript DOM 이벤트 사용시에도 많이 사용된다
useState를 State를 만들어주기 위해 React에서 제공하고 React에서만 존재하는 기능이다
이런 기능을 Hook이라고 부른다
React를 사용하면서 불변성에 주의를 해야한다
Immutable type
불변성(Immutability)란 말그대로 변하지 않는 것을 의미한다
(메모리의 값을 변경할 수 없는 것)
불변 데이터는 한번 생성되고나면 그 뒤에는 변할수 없다
자바스크립트에는 원시 타입(primitive type)으로는 Boolean, String, Number, Null, undefined, Symbol이 있으며 이 원시 타입은 불변한다
이 값은 메모리영역 안에서 변경이 불가능하며 변수에 할당할 때 완전히 새로운 값이 만들어져 재할당된다
Mutable type
자바스크립트에서는 위에 나열한 immutable type을 제외하고 모든 값은 객체(Object)타입이며 변할 수 있는 값이다
객체는 새로운 값이 만들어지지 않고 직접적으로 변경이 가능하다
[출처]https://sustainable-dev.tistory.com/156
정리가 잘 되어 있어서 이해를 도와준다
📍 그렇다면 왜 React에서 불변성이 중요한 지 알아보야아 한다
React에서는 리렌더링 할 지 말지를 결정할 때 State의 변화를 확인한다
(변했으면 리렌더링, 안 변했으면 리렌더링 하지 않는다)
이 때 변화를 확인하는 방법이 State 변화 전 후의 메모리 주소를 비교한다
만약 원시데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지 않고 직접 수정하게 되면
값은 바뀌지만 메모리 주소는 그대로이다
그래서 값은 변경되어도 React에서는 State가 변한 것을 인지하지 못하므로
리렌더링이 일어나야 하는 상황에도 할 수 없게 된다
setName([...name, "변경할 값"])
그래서 Spread Operator(전개 연산자)를 사용하여 기존 값을 추가하고
그 이후에 값을 추가하거나 수정하는 방식으로 구현해야 한다
일단 배포는 완료..
개인과제 TodoList
설명은 내일..