본 포스팅은
inflearn의 'React & Express 를 이용한 웹 어플리케이션 개발하기' 강좌 내용을 포함하고 있습니다.
링크: https://www.inflearn.com/course/react-%EA%B0%95%EC%A2%8C-velopert#
"React.JS is...a JavaScript library for building user interfaces."
React Native 란?
- 서버 사이드 렌더링의 장점 : 초기 렌더링을 서버 사이드 렌더링으로 할 경우, 유저에게 쾌적한 사용경험(User Experience)을 제공할 수 있음 - 클라이언트 사이드 렌더링은 초기 구동 딜레이가 있기 때문. 서버 측에서 HTML을 미리 생성해서 문자열 형태로 브라우저에 띄움. SEO(Search Engine Optimization; 검색엔진최적화)지원 가능. 다만 서버측의 자원을 쓰게 되는 것은 불가피하기 때문에 컴퓨터 성능이 좋지않고 방문자가 많다면 추천하지 않음.
<컴포넌트명/>
형식으로 쓰임. 소문자로 쓰면 <div>
나 <span>
같은 HTML 태그로 해석되기 때문에 반드시 대문자로 시작해야함.
- static method: 클래스를 위한 정적(static) 메소드를 정의함. 정적 메소드는 클래스의 인스턴스화(instantiating) 없이 호출되며, 클래스의 인스턴스에서는 호출할 수 없다. 주로 어플리케이션(application)을 위한 유틸리티(utility) 함수를 생성하는데 사용된다.
-MDN
//ES6 class 예시 - Codelab 컴포넌트 만들기
class Codelab extends React.Component {
render() {
return(
<div>Codelab</div>
);
}
}
extends React.Component
: ES6 클래스를 사용해서 컴포넌트를 만드는 방법. 말 그대로 React.Component 클래스를 상속함.//JSX
var a = (
<div>
welcome to <b>React CodeLab</b>
<div>
);
/* ()를 사용하지 않아도 오류는 발생되지 않지만 가독성을 위해 사용을 권장 */
⬇️⬇️⬇️
//native JavaScript
'use strict';
var a = React.createElement(
"div",
null,
"Welcome to",
React.createElement(
"b",
null,
"React.js CodeLab"
)
);
ReactDOM.render()
: 실제 페이지에 JSX 형태의 코드를 렌더링할 때 사용된다. 첫번째 인자는 '렌더링 하고자하는 JSX형태 코드'. 두번째 인자는 '이 컴포넌트를 렌더링 할 엘리먼트'. <!--HTML divider-->
<div id="root"></div>
//App 컴포넌트
class App extends React.Component {
render() {
return (
<Codelab/> /*App 컴포넌트가 Codelab 컴포넌트를 보여준다.*/
);
}
}
//ReactDOM.render() 예시
ReactDOM.render(<App/>, document.getElementById('root'));
- Nested Element:
모든 JSX 형태의 코드는 container element 안에 포함시켜야 한다. 무언가로 감싸져야만 코드가 제대로 작동함.
//에러발생
render() {
return (
<h1>Hello</h1>
<h2>This is an error</h2>
)
}
//올바른 코드: container element <div> 태그 포함
render() {
return (
<div>
<h1>Hello</h1>
<h2>Yay, the error is gone!</h2>
</div>
)
}
- JavaScript Expression:
JSX안에서 JavaScript 를 표현할 때는{}
으로 wrapping을 해야한다.
render() {
let text = "Hello World!";
return (
//text 변수를 {} 으로 감싸주기
<div>{text}</div>
);
}
- Inline Style:
Style을 설정할 때는 (String 형식을 사용하지 않고) key가 camelCase인 객체를 사용해야 한다.
//key가 camelCase인 객체 사용
render() {
let style = {
color: '#f5f6fa',
fontSize: '50px',
backgroundColor: '#f6b93b'
};
//여기서도 style변수는 {}으로 감싸주기
return (
<div style={style}>Hello World</div>
);
}
//class를 설정할 때는 class= 가 아닌 className= 을 사용하기
render() {
return (
<div className='box'>Hello World</div>
);
}
- Comments:
주석을 작성할 떄는{/* ... */}
형식 안에 작성하기.
*주의: 주석 역시 Nested Element 로 container element 내부에 작성되어야 함.
//comment가 container element인 <div>tag 밖으로 넘어가면 error 발생
render() {
return (
<div>
{/*This is how you write the comment*/}
{/*Multi-line
testing*/}
Hello Strangers
</div>
);
}
{this.props.propsName}
propsName = "value(값)"
형식으로 작성.this.props.children
은 모든 컴포넌트가 기본적으로 갖고있는 props로서, <컴포넌트명></컴포넌트명>
사이의 값이 들어감. //Codelab컴포넌트 (하위)
class Codelab extends React.Component {
render() {
return (
<div>
<h1>Hello {this.props.name}</h1> /*velopert*/
<div>{this.props.children}</div> /*여기에 보여지는 것이 바로 props.children*/
</div>
);
}
}
//App 컴포넌트 (상위)
class App extends React.Component {
render() {
return (
<Codelab name="velopert">여기에 보여지는 것이 바로 props.children</Codelab>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
Output ➡️
한 단계 더 나아가 아래와 같이 App 컴포넌트의 <Codelab name=" velopert">
중 velopert
라는 text 대신에 {this.props.name}
을 넣어 또 다른 props를 설정할 수 있다.
그리고 위 예제에서 여기에 보여지는 것이 바로 props.children
이라고 보여지는 곳에 {this.props.children}
을 대신해 자체적으로 props를 만들어줄 수도 있다.
//Codelab컴포넌트
class Codelab extends React.Component {
render() {
return (
<div>
<h1>Hello {this.props.name}</h1>
<div>{this.props.children}</div>
</div>
);
}
}
//App 컴포넌트
class App extends React.Component {
render() {
return (
<Codelab name={this.props.name}>{this.props.children}</Codelab>
);
}
}
ReactDOM.render(<App name=" velopert">I am your child</App>, document.getElementById('root'));
Output ➡️
Component.defaultProps = {...}
기본값을 설정할 때는 컴포넌트 선언이 끝난 후, defaultProps
객체를 설정하면 된다.
//App 컴포넌트
class App extends React.Component {
render() {
return (
<div>{this.props.value}</div>
);
}
};
//defaultProps 객체
App.defaultProps = {
value: 0 /*value props의 기본값을 0으로 설정*/
};
Component.propTypes ={...}
이 기능으로 특정 props값이 특정 type이 아니거나, 필수 props인데 입력하지 않았을 경우, console창에서 경고를 표시하도록 할 수 있다.
type를 검증할 때는 컴포넌트 선언이 끝난 후, props.propTypes
객체를 설정하면 된다.
//App 컴포넌트
class App extends React.Component {
render() {
return (
<div>
{this.props.value}
{this.props.secondValue}
{this.props.thirdValue}
</div>
);
}
};
//propTypes 객체
App.propTypes = {
value: React.PropTypes.string, /*첫번째 값은 string타입*/
secondValue: React.PropType.number, /*두번째 값은 number타입*/
thirdValue: React.PropTypes.any.isRequired /*세번째 값은 타입상관없이 필수입력*/
};
isRequired
가 입력되면 필수입력항목으로 지정된다.
propTypes를 지정하는 것은 필수가 아니다. 그러나 유지보수와 효과적인 활용을 위해서 설정하는 것.
대표적인 예로 여러가지 컴포넌트를 사용하는 프로젝트를 하는 경우, 각각의 컴포넌트가 하는 어떤 props를 필요로 하고, 어떤 type이어야 하는지 빠르게 파악할 수 있도록 도움.
//Codelab컴포넌트
class Codelab extends React.Component {
render() {
return (
<div>
<h1>Hello {this.props.name}</h1>
<h2>{this.props.number}</h2>
<div>{this.props.children}</div>
</div>
);
}
}
//Codelab 컴포넌트 propType 설정
Codelab.propTypes = {
name: PropTypes.string,
number: PropTypes.number.isRequired
};
//Codelab 컴포넌트 기본값 설정
Codelab.defaultProps = {
name:'Unknown'
}
//App 컴포넌트
class App extends React.Component {
render() {
return (
<Codelab name={this.props.name} number={this.props.number}>{this.props.children}</Codelab>
);
}
}
ReactDOM.render(<App name={'Scarelet'} number={25}>You are such a lovely person!</App>, document.getElementById('root'));
Output ➡️
{this.state.stateName}
this.state ={}
으로 설정.this.state ={}
는 절대 재사용하지 말 것.this.setState({})
로 변경이 가능하다. 달리 말하면, 생성자에서는 사용이 안된다는 뜻. 성능이 떨어짐.class Counter extends React.Component {
//초기값 설정
constructor(props){ /*props는 Counter가 만들어질 때 전달받을 매개변수*/
super(props); /*super를 통해 React.Component를 먼저 실행해 접근성을 확보*/
this.state = {
value: 0
}
this.handleClick = this.handleClick.bind(this);/*this binding 해주기*/
}
//버튼이 클릭될 때 실행될 메소드
handleClick(){
this.setState({ /*binding을 해주지 않으면 this가 뭔지 모른다!*/
value: this.state.value + 1
})
}
render() {
return (
<div>
<h2>{this.state.value}</h2>
<button onClick={this.handleClick}>Press Me</button>
</div>
)
}
}
class App extends React.Component {
render() {
return (
<Counter/>
);
}
};
ReactDOM.render(
<App></App>,
document.getElementById("root")
);
super(props);
로 상속받은 class인 React.Component
(Parent의 생성자 메소드)를 먼저 실행시킨다. 이 과정이 먼저 실행되어야 this.state
와 같은 메소드에 접근할 수 있음.onClick
을 그대로 사용해서 클릭이벤트를 추가할 수 있음.<button onClick={this.handleClick.bind(this)}>Press Me</button>
은 handleClick()
에서 사용되는 this
는 render()
에서 사용되는 this
와 같다는 뜻이 된다. 이렇게 binding을 해주지 않으면handleClick()
내부의 this
가 무엇인지 모르기 때문. 이렇게도 binding이 가능하나, 관습적으로 위 예시와 같이 Constructor 내부(this.handleClick = this.handleClick.bind(this);
)에 binding 해주는 것이 나음.<button onClick={this.handleClick}>Press Me</button>
)에서 handleClick
은 괄호없이 기재되어야만 불필요한 실행을 방지할 수 있다는 것이다. map()
메소드를 사용.map()
메소드는 매개변수로 전달 된 함수를 통해 배열의 각 요소를 처리해서 그 결과로 새로운 배열을 생성한다.arr. map(callback, [thisArg])
class Contactinfo extends React.Component {
render() { /*객체형 props를 사용해 이름과 번호를 렌더링*/
return (
<div>
{this.props.contact.name}{this.props.contact.phone}
</div>
)
}
}
class Contact extends React.Component {
/*생성자 메소드에서 state초기설정*/
constructor(props){
super(props);
this.state = {
contactData: [
{name: '김수환무', phone: '010-1111-2222'},
{name: '거북이', phone: '010-1111-3333'},
{name: '두루미', phone: '010-1111-4444'},
{name: '삼천갑자', phone: '010-1111-5555'}
]
}
}
render() {
const mapToComponent = (data) => {
/*새로운 배열을 만들어서 리턴*/
return data.map((contact, i) => {
return (<Contactinfo contact = {contact} key = {i}/>)
})
}
return (
/*반복되는 부분을 또 다른 컴포넌트로 생성(Contactinfo)*/
/*mapToComponent 함수사용가능. (this.state.contactData)는 매개변수*/
<div>
{mapToComponent(this.state.contactData)}
</div>
)
}
}
class App extends React.Component {
render() {
return (
<Contact/> /*Contact 컴포넌트 렌더링*/
);
}
};
ReactDOM.render(
<App></App>,
document.getElementById("root")
);
return (<Contactinfo contact = {contact} key = {i}/>) })
에서 key = {i}
를 사용하는 이유는 각 데이터에 아이덴티티(identity)를 주기 위해서.*본 포스팅은 아래 사이트들을 참고 및 인용하여 작성되었습니다.
학습단계로 잘못된 정보가 있을 수 있습니다. 잘못된 부분에 대해 알려주시면 곧바로 정정하도록 하겠습니다 😊
https://m.blog.naver.com/manddonara/119738492
https://moolgogiheart.tistory.com/87
https://ko.reactjs.org/docs/react-component.html
https://medium.com/@yeon22/react-js-react-js%EC%9D%98-props-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95-bc59a5c257a
https://medium.com/@ljs0705/babel-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-a1d0e6bd021a
감사합니다 ㅜㅜ 진짜진짜 도움많이 됐어요!