와 내가 드디어 리액트를 해본다
리액트 - JSX
JSX (Javascript XML)는 Javascript에 XML을 추가 확장한 문법!
리액트로 프로젝트를 개발할 때 사용하고 공식적인 문법은 아님!
또한 브라우저에서 실행하기 전에 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환된다.
* Babel은 최신 ES6버전을 구 버전인 ES5로 변환해준다.
또한 JSX문법을 Javascript 문법으로 변환하는 기능도 가지고 있으며,
React에서 JSX를 사용할 수 있게하는 핵심적인 역할을 함
<script type="text/babel" src="./app.js"></script>
그래서 jsx문법 적용시 스크립트를 불러올 때 타입을 babel로 지정해줘야한다.
createElement() 적용
(1) 첫번째 파라미터 → 태그명
(2) 두번째 파라미터 → 태그 내부의 속성명으로 변경
(3) 세번째 파라미터 → 모두 자식노드로 변경
const box = React.createElement(
"div",
{className : "tay"},
title, content
);
ReactDOM.render(box, document.querySelector("#root"));
JSX 문법 적용
- class는 className, for는 htmlFor, id는 data-id
- 자바스크립트 표현식 (Javascript Expression)도 사용가능!
{ } 안에다 작성하면 되고 유효한 모든 자바스크립트 표현식을 넣을 수 있따.
- JSX 내부에 여러 요소가 있을 경우 반드시 부모 요소로 감싸야한다 ( <> </> )
- JSX 최상위 root는 하나의 태그로만 구성
- 태그 내부에 속성값을 변경해야할 때는 <태그명 속성명={ *변수명 }></태그명>
- 태그 자식노드로 변동값을 주어야 할 때는 <부모태그명>{ *변수명 }</부모태그명>
- 주석은 {/* 주석 */} 이렇게
const box = (
<div className="tay">
{[title, content]}
</div>
);
ReactDOM.render(box, document.querySelector("#root"));
또한 자식 노드가 존재하는 경우, 변수를 별도로 만들기보다는 부모 아래 자식노드를 JSX 문법으로 변경한다.
const box = (
<div className="tay">
<h1 title='txtTitle'>My Title</h1>
<p>콘텐츠 공간입니다.</p>
</div>
);
ReactDOM.render(box, document.querySelector("#root"));
표현식을 활용하여 동적으로 표현방식 적용도 가능
let strTitle = "테이";
let strText = "리액트 좋아요";
const box = (
<div className="tay">
<h1 title={strTitle}>My Title</h1>
<p>{strText}</p>
</div>
);
ReactDOM.render(box, document.querySelector("#root"));
JSX 에서 가능한 표현식
삼항조건연산자(A < B ? true : false), map(), filter(), every, include, 배열함수메서드만 작성 가능
JSX 에서 불가능한 표현식
변수선언 불가, if, for문 사용불가
리액트 - 컴포넌트
React.Component 에서는 지정된 장소를 대문자로 시작을 구성.
소문자로 시작되었다면 일반적인 태그로 인식을 하기 때문에!
1. 클래스형 컴포넌트 : Class로 컴포넌트 구성 (React 16버전 이하에서 사용 (2019년 9월 이전))
- 컴포넌트 구성요소, 리액트 생명주기를 모두 포함
- 프로퍼티, state, 생명주기 함수가 필요한 구조의 컴포넌트를 만들 때 사용
class Hello1 extends React.Component {
render(){
const userName = "BTS";
return <h3>Hello, {userName}</h3>
}
}
리액트를 extends함
2. 함수형 컴포넌트 : hooks(함수형)로 Component 구성(React 17버전 이후 사용 (2019년 9월 이후))
- 가장 간단하게 컴포넌트를 정의할 수 있음
const Hello2 = () => {
const userName = "아이유";
return <h3>Hello, {userName}</h3>
}
더 심플해짐
리액트 - 프로퍼티 (props)
props의 역할은 상태정보를 갖고 있다면 이 상태 정보를 다른 컴포넌트가 공유하고자 할 때 전달자의 역할을 담당
props는 위(상위 부모)에서 아래(하위 자식)으로 흐른다. (단방향 데이터 흐름)
또한 프로퍼티는 수정할 수 없다는 특징이 있다. (자식 입장에서는 읽기 전용 느낌)
문자열을 전달할 때 → 큰따옴표(" ")
문자열 외의 값 전달할 때 → 중괄호 ({ })
const root = document.querySelector("#root");
const StudentScore = (props) => {
console.log(props);
return (
<>
<div>{props.name}학생의 {props.title} </div>
<div>{props.name}학생의 수학 점수는 {props.mathScore} 점 </div>
<div>{props.name}학생의 국어 점수는 {props.korScore} 점 </div>
<div>{props.name}학생의 영어 점수는 {props.engScore} 점 </div>
</>
);
}
const App = (props) => (
<StudentScore name="홍길동" title="시험 성적" mathScore="95" korScore="75" engScore="80"></StudentScore>
);
ReactDOM.render(<App />, root);
↓ 해석
순서2. 자식 영역으로 상위로부터 전달 받은 데이터 값을 활용
const StudentScore = (props) => {
console.log(props); // 부모로부터 받은 것 {name: '홍길동', title: '시험 성적', mathScore: '95', korScore: '75', engScore: '80'}
return (
<>
<div>{props.name}학생의 {props.title} </div>
<div>{props.name}학생의 수학 점수는 {props.mathScore} 점 </div>
<div>{props.name}학생의 국어 점수는 {props.korScore} 점 </div>
<div>{props.name}학생의 영어 점수는 {props.engScore} 점 </div>
</>
);
}
순서1. 상위 부모 영역에 props를 등록. 하위 컴포넌트인 전달자 역할
const App = (props) => (
<StudentScore name="홍길동" title="시험 성적" mathScore="95" korScore="75" engScore="80"></StudentScore>
);
순서3. 돌려 받은 값을 지정한 장소에 넣는다.
ReactDOM.render(<App />, root);
또한 고정형 데이터가 아닌 배열형 데이터도 처리가능!!
const classScore = [
["피카츄", 45, 80, 70],
["파이리", 80, 60, 15],
["꼬부기", 90, 66, 28],
["이상해", 95, 47, 66],
["라이츄", 20, 78, 51],
["이브이", 50, 76, 12],
];
const StudentScore = (props) => {
console.log(props);
return (
<>
<div>{props.name}학생의 {props.title} </div>
<div>{props.name}학생의 수학 점수는 {props.mathScore} 점 </div>
<div>{props.name}학생의 국어 점수는 {props.korScore} 점 </div>
<div>{props.name}학생의 영어 점수는 {props.engScore} 점 </div>
<hr />
</>
);
}
const App = (props) => (
<>
{classScore.map((v,i)=>(
<StudentScore name={v[0]} title="시험 성적" mathScore={v[1]} korScore={v[2]} engScore={v[3]} key={i}></StudentScore>
))}
</>
);
ReactDOM.render(<App />, root);
리액트 - 상태 (state)
state는 컴포넌트에서 동적인 값.
일반적으로 컴포넌트 내부에서 변경 가능한 데이터를 관리할 때, 동적인 데이터를 다룰 때 사용
컴포넌트 내부에서 값을 바꿀 수 없음!
변화가 필요한 경우 setState() 함수를 통해 기존의 값을 변경 할 수 있음
- 클래스 함수 활용
// 함수 파트, 렌더링 파트
class Counter extends React.Component{
// 상품의 최총 수량을 설정
state = {
number : 1
};
// 우선자 설정
plus = () => {
console.log(this); // Counter
console.log(this.state); // {number: 1}
console.log(this.state.number); // 1
this.setState({
number : this.state.number + 1
});
}
// 우선자 설정 (최소 수량이 1) ==> 입력상자 내부의 value 값이 1인 경우, 추가 클릭시 alert창에 최소 수량은 1입니다.
minus = () => {
if(this.state.number < 2){
this.setState({
number : this.state.number
});
alert("최소 수량은 1입니당");
}else{
this.setState({
number : this.state.number - 1
});
}
}
render(){
const {number} = this.state;
console.log(number);
return (
<>
<div className="col-lg-4 d-flex justify-content-center align-items-center py-4 mx-auto">
<div className="form-control form-text text-center">
<label className="my-4">상품수량</label>
<div className="input-group form-text d-flex justify-content-center">
<button className="btn btn-secondary" onClick={this.plus}>+</button>
<input className="input-group-text" type="number" value={number} />
<button className="btn btn-secondary" onClick={this.minus}>-</button>
</div>
</div>
</div>
</>
);
}
}
class App extends React.Component{
render() {
return <Counter/>
}
}
- useState() 와 hook 이라는 함수 적용
useState : 현재 상태와 앞으로 변경되게할 과정을 구성
const {useState} = React; // React에서 제공하는 상태관리 함수 메서드
const App = () => {
// 메서드 파트
const [num, setNum] = useState(1);
console.log(num); // 1
// num 은 한번 선언되면 끝
// setNum 은 변동 어쩌구 ...
const plus = () => {
console.log("더하기!");
setNum(num+1);
}
const minus = () => {
console.log("빼기!");
if(num < 2){
alert("최소 수량은 1임 ㅗ");
} else{
setNum(num-1);
}
}
// 렌더링 파트
return (
<>
<div className="col-lg-4 d-flex justify-content-center align-items-center py-4 mx-auto">
<div className="form-control form-text text-center">
<label className="my-4">상품수량</label>
<div className="input-group form-text d-flex justify-content-center">
<button className="btn btn-secondary" onClick={plus}>+</button>
<input className="input-group-text" type="number" value={num} />
<button className="btn btn-secondary" onClick={minus}>-</button>
</div>
</div>
</div>
</>
);
}
ReactDOM.render(<App/>, root);
아웅 복잡해
리액트 공부는 자바스크립트랑 뷰 마스터하고 하겠음
당분간 ㅃㅇ