리액트 컴포넌트의 역사
// * 첫 번째 인자는 만들려는 엘리먼트의 타입을 문자열로 정의한다.
// * 두 번째 인자는 만드는 엘리먼트의 프로퍼티를 표현한다.
// * 세 번째 인자는 엘리먼트의 자식 노드(텍스트노드)를 표현한다.
const greetingElement = React.createElement('h1', {id : "greeding1" } , 'hello world');
// 결과
<h1 id="greeding1"> hello world </h1>
라는 Element ( 리액트 에서는 일반적으로 컴포넌트 라는 개념으로 더 많이 알려져있다. )
가 생성된다.
옛날에는 정말 엿같은 방식으로 컴포넌트를 만들고 있었네요
그 이후에도 몇 가지 방법들이 추가가 되었지만
createClass 함수
클래스형 컴포넌트
리액트 16버전 이후로는 ‘함수형 컴포넌트’ 를 주로 사용하고 있습니다.
function Hellowolrd() {
return React.createElement(
'h1',
{className : 'greeting'},
'Hello world!'
);
}
// 함수 이름
ReactDOM.render(React.createElement(Hellowolrd) , document.getElementById('root'));
뭐지 정리해보고나니까 달라진게 없는데요 ??? ?????????????????? (바벨을 아직 적용 안해서)
바벨 이라는 문법 변환 도구를 적용 한 뒤, ( 밑에 JSX 내용을 보고 오면 더 좋음 )
function Title2() { // 1. 함수 만들어 (첫글자 대문자 !!)
return( // 2. 리턴 만들어
<h1>함수형 컴포넌트</h1> // 3. JSX 엘리먼트 만들어
);
}
ReactDOM.render(<Title2/>, document.getElementById('root'));
ReactDOM.render(element, container) 인자(args) 정리
element = 내가 만든 DOM
container = 어느 노드에 넣을지 (그 노드가 부모가 되고, 내가 만든 DOM은 자식이 된다 )
JSX가 무엇인가
JS (JavaScript) + XML 로써 자바스크립트를 확장한 문법이라고 설명하겠습니다.
위에서 설명한 컴포넌트 작성 방법을 조금ㄷ ㅓ~~~ 깔끔하게 도와주는 문법입니다.
JSX 는 공식적인 자바스크립트 문법이 아니기 때문에 바벨(babel) 이라는 문법 변환 도구가 필요합니다.
이는 문서 맨 윗 단에 CDN 한 줄을 추가 해주시면 됩니다
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
JSX 문법 (스타일 관련은 그냥 거르세요 중요X)
xml 문법- 반드시 닫기 태그 와 함께 사용
ex) <key>value</key>
ex) <key/>--셀프클로징(자식노드에 값이없을때)
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
렌더링 할 요소는 최상위 엘리먼트 하나 만 있어야한다.
// const element = (<h1> Hello, {user.name} </h1>
// <h3> Hello, {user.phone} </h3>); // 불가능
// 하나의 돔 트리로 만들면 가능
// const element = (
// <div>
// <h1> Hello, {user.name} </h1>
// <h3> Hello, {user.phone} </h3>
// </div> ); // 가능
// <React.Fragment>로 감싸서 형식상의 돔트리상 상위 엘리먼트를 만들어준다.
// React 16 버전에서 추가 된 기능으로 별도의 노드를 추가하지않고 여러자식을 그룹화한다.
// 위의 div와 같이 불필요한 DOM node 생성을 막기 때문에 메모리를 적게 사용한다
// const element = (
// <React.Fragment>
// <h1> Hello, {user.name} </h1>
// <h3> Hello, {user.phone} </h3>
// </React.Fragment>
// )
// React.Fragment 의 축약 문법 ( 그냥 아무것도 안써도 됨)
const element =(
<>
<h1> Hello, {user.name} </h1>
<h3> Hello, {user.phone} </h3>
</>
);
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
속성값(Attribute) 적용방법
JSX는 html 태그처럼 보이지만 실제로는 자바스크립트이다.
(React.createElement를 호출하는 코드로 컴파일된다.)
따라서 자바스크립트의 예약어와 동일한 이름의 attribute는
다른 이름으로 우회적으로 사용하도록 정의되어 있다.
// const element = (
// <div>
// <h1> Hello, {user.name} </h1>
// <h3> Hello, {user.phone} </h3>
// </div> );
즉 작성은 이렇게 하지만 바벨로 변환하고 나면 실제 실행은 위에 봤던 엿같은 코드로 실행된다는
이야기.
// 1. 문자열로 속성값 정리하는 방법
// const element = <h1 id="title" className="light"> Hello world~</h1>;
// 2. JavaScript 표현식 ({}) 을 이용하여 정의하는 방법
const id = "title";
const className = "light"
const element = <h1 id= {id} className = {className}> Hello world~</h1>;
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
컴포넌트에 스타일 적용하기 ( 내부 )
/* 스타일을 적용하기 위한 객체의 속성명은 카멜케이스로 작성해야 한다.
* 예) background-color -> backgroundColor
* 속성값은 문자열 혹은 숫자 형태로 작성해야 한다.
* */
// 스타일 객체
const styleVal = {
backgroundColor : 'black',
color : 'white',
cursor : 'pointer',
textAlign : 'center',
padding : 20
}
const element = (
<> // 객체 때려박기
<h1 style = {styleVal}> Hello world</h1>
<h3> inline styling test</h3>
</>
);
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
이벤트 처리하기
// 1. 인라인으로 간단한 이벤트 적용 시 JSX의 자바 스크립트 표현식 내에 이벤트처리 함수 작성
// const element = (
// <>
// <h1> Event Attribute</h1>
// <button onClick = {function(){alert('Hello world')}}> 클릭하세요</button>
// <button onClick = {() => alert('Hello arrow world')}> 클릭하세요</button>
// </>
// )
// 2. 이벤트 동작 시 사용할 핸들러 메소드를 사전 정의 후 JSX 내에 표현식으로 사용
const onClickHandler = () => {
alert('Hello');
}
const onClickHandler2 = function (){
alert('Hello2');
}
const element = (
<>
<h1> Event Attribute</h1>
<button onClick= {onClickHandler2}> 클릭하세요 핸들러 </button>
</>
)
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
조건부 렌더링 ( if문 사용 불가 )
아직 정확한 조건은 모르겠지만 JSX 에서 IF 문 사용을 권장하지 않는것 같다.
어디에선 써지고 어디에선 안써진다...
그래서 이러한 방법으로 조건을 확인 할 수 있다.
1. 삼항연산자 (아니깐 패스)
2. && 문법
true만 확인 할 수 있는 조건문 이다.
1 == 1 && <p> 트루입니다 !</p>
3. 즉시발동함수 https://myhappyman.tistory.com/60
const word = 'react';
return (
<div>
{
(function(){
if(word == 'react'){
return ("리액트!")
}else if(word == 'hello'){
return ("헬로우!")
}else if(word == 'world'){
return ("월드!")
}
})()
}
</div>
);
3.1 즉시발동함수 화살표함수
(()=>{
if(word == 'react'){
return ("리액트!")
}
})
JSX 문법으로 위에서 만든 컴포넌트랑 똑같은 컴포넌트를 만들어보겠습니다.
<script type = "text/babel">
const helloworld = <h1> hello world </h1>;
ReactDOM.render(helloworld, document.getElementById('root'));
</script>
helloworld 변수에 HTML 코드를 냅다 넣고있는데 오류가 없습니다.
컴포넌트 합성
const user = {
name: '홍길동',
age: 20,
phone: '010-1234-5678',
email: 'hong123@gmail.com'
}
function NameCard() {
return <h1>{user.name}</h1>
}
function AgeCard() {
return <h1>{user.age}</h1>
}
function PhoneCard() {
return <h1>{user.phone}</h1>
}
function EmailCard() {
return <h1>{user.email}</h1>
}
// 각각의 컴포넌트 들을 감싸는 컴포넌트
function UserInfo() {
return (<div style={{width:300 , border: '1px solid black'}}>
<NameCard/>
<AgeCard/>
<PhoneCard/>
<EmailCard/>
</div>);
}
ReactDOM.render(<UserInfo/>, document.getElementById('root'));
배우진 않았지만 State 혼자 정리
State (상태)는 컴포넌트가 갖고있는 속성값 입니다. 이 속성값이 변하면 리액트 엔진은 자동으로 UI를 업데이트 시켜줍니다.
state 실습예제를 하려면 import 가 필요한데 예제를 전부 html 에서 해서 ㅠㅠ
나중에 추가하겠습니다.
props
properties의 약어로, 컴포넌트의 속성을 설정할 때 사용하는 요소이다.
부모에게 받아온 데이터입니다.
리액트의 Data Flow는 단방향 형식으로 부모에서부터 자식으로 이동하기 때문에 거꾸로 올라갈 수 없습니다.
따라서 props에 있는 데이터들은 수정이 불가능하며 오직 안에있는 값을 꺼내서 사용할수만 있습니다.
>> 라고 처음엔 생각했지만 ? useState 의 기능으로 상태값 관리를 하게된다면 말이 달라질지도 ...
props 기본 렌더링
const name1 = '이대엽';
const name2 = 'dleoduq';
// 2. xxx 에 name1 을 전달해서 표현 매개변수에 props, state 라고 적어주는게
// 규칙 이라는듯 !?
function Title2(props) {
console.log(props);
return <h1> 안녕하세요 {props.name} 님~! </h1>
}
ReactDOM.render(
<Title2 name = {name1}/>, document.getElementById('root')
);
자바스크립트로 선언된 변수를 JSX 에서 쓰고싶다면,
{ 변수이름 } 중괄호를 씌워주면 된다.
자식노드 렌더링
자식 노드를 전달하는 props.children 리액트 컴포넌트를 사용할 때 태그 사이의 내용을 props의 children 속성에서 관리한다.
function ChildNodePrinter(props) {
console.log(props);
return (
<>
<h1>자식노드가 가지고 있는 값은</h1>
<h3>Children : <font style={{color : 'orange'}}>{props.children}</font> </h3>
</>
)
}
ReactDOM.render(
[
<ChildNodePrinter>텍스트노드</ChildNodePrinter>,
<ChildNodePrinter><div>자식노드</div></ChildNodePrinter>,
<ChildNodePrinter><div>1</div><div>2</div><div>3</div></ChildNodePrinter>
],
document.getElementById('root')
)
결과 >>
props 구조분해할당 https://youtu.be/lV7ulA7R5Nk?t=178
구조분해할당 : 배열이나 객체의 속성을 구분해서 그 값을 변수에 담을 수 있게 하는 표현식
중괄호로 감싼 변수로 제시한 속성 {name, children} 에
props 객체의 속성과 이름이 일치하면, 그 값을 부여하는 기능입니다.
const {name, children} = props; 는 아래와 같다
const name = props.name;
const children = props.children;
리액트를 이래저래 다루다 보니 알게모르게 배열 구조분해할당, 객체 구조분해할당을 굉장히 많이 사용하고 있길래
제 생각엔 절대 모르면 안될 내용일 것 같습니다.
// 전달 받는 인자를 바로 비구조화 할당
function PropsPrinter(props) {
// 비구조화 할당을 하게 되면 공통적으로 사용하는 props.을 생략하고 사용할 수 있다.
console.log(props); // {name: 'dleoduq', children: '문자열자식'} 객체 타입이다
const {name, children} = props;
/*
const {name, children} = props; 는 아래와 같다
const name = props.name;
const children = props.children;
*/
return (
<>
<h1>제이름은 {name} 입니다</h1>
<h3>제가 가지고있는 자식은 {children} 입니다</h3>
</>
)
}
ReactDOM.render(<PropsPrinter name = "dleoduq" children = "문자열자식"/>
, document.getElementById('root'));
props 에 전달되는 타입 검증
근데 콘솔에서만 오류를 알려주던데 어떻게 사용하는걸까 ?? - 고민해결되면 수정할 것 ( 아니 수정안할거< <이게 수정임)
propTypes 를 이용하기 위해 CDN 추가
function PropsVerify({name, favoriteNumber, children}) {
return (
<>
<h1>제이름은 {name}</h1>
<h1>제가 가잫 좋아하는 숫자는 {favoriteNumber}</h1>
<h1>제가 가지고있는 children은 {children}</h1>
</>
)
}
// 문법
PropsVerify.propTypes = {
name : PropTypes.string, // 문자열인지 검증
favoriteNumber : PropTypes.number.isRequired // 숫자형인지 검증, 값을 입력했는지 검증
}
ReactDOM.render(
[
<PropsVerify name="이대엽" favoriteNumber={5}>텍스트노드</PropsVerify>,
<PropsVerify name="이대엽" favoriteNumber={5}>자식 텍스트노드</PropsVerify>,
/*중괄호 씌우면 숫자*/
<PropsVerify name={3} favoriteNumber={5}>자식 텍스트노드</PropsVerify>, // name string 무시
<PropsVerify name="이대엽3" >자식 텍스트노드</PropsVerify> // isRequired 무시
]
, document.getElementById('root'));
'더존 노션 필기 옮기기 > React' 카테고리의 다른 글
react 2번째 정리 useState, useEffect, useReducer, useContext (0) | 2022.09.15 |
---|---|
React 비상사태 (0) | 2022.09.08 |