Search

React

자바 스크립트안에 html태그를 넣는걸 JSX라고 한다.
index.html → html파일
index.js → render메소드로 html태그를 만들어준다.
render : 순수한 자바스크립트 문법이 아니라, 리액트 개발용 문법이다.
첫 argument: html 요소를 만듬
두번째 argument: dom요소들 중 root id를 가진 element
두번째 argument 안에 첫 argument 를 집어넣는다.

JSX

class를 className으로 써야한다.
for라는 속성도 쓸 수 없다. JSX문법으로 for라는 속성을 사용하려면, htmlFor 라고 써줘야한다.
이벤트 핸들러의 이름도 약간 다르다.
onblur → onBlur
onfocus → onFocus
onmousedown → onMouseDown
render함수 안에는 한 태그로 감싸져야한다.
이를 방지하기 위해서 <Fragment>를 쓴다.
import { Fragment } from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( <> <h1 id="title">가위바위보</h1> <button class="hand">가위</button> <button class="hand">바위</button> <button class="hand"></button> </> , document.getElementById('root') );
JavaScript
복사
{}안에서는 자바스크립트를 모두 실행할 수 있다.
import ReactDOM from 'react-dom'; const product = 'MacBook'; const model = ' Air' const item = product + model const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/MacBook' function handleClick(){ alert('곧 도착합니다'); } ReactDOM.render( <> <h1>나만의 {item} 주문하기</h1> <img src = {imageUrl} alt = "제품 사진"/> <button onClick = {handleClick}>확인</button> </>, document.getElementById('root') );
JavaScript
복사
다만 {}안에는 자바스크립트의 표현식만 사용가능하다.
if문이나 for문과 같은 문장식은 사용불가

컴포넌트

import ReactDOM from 'react-dom'; function Hello(){ return <h1>안녕 리액트</h1> } const element = ( <> <Hello /> <Hello /> <Hello /> </> ); ReactDOM.render( element, document.getElementById('root') );
JavaScript
복사
컴포넌트는 항상 대문자여야한다.

Props

import React, { Component } from 'react'; import './App.css' class Toc extends Component { render() { return ( <nav> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> </nav> ); } } class Content extends Component { render() { return ( <article> <h2>HTML</h2> HTML is HyperTextMarkup Language </article> ); } } class Subject extends Component { render() { return ( <header> <h1>{this.props.title}</h1> {this.props.sub} </header> ); } } class App extends Component { render() { return ( <div className="App"> <Subject title="WEB" sub="world wide web"></Subject> <Subject title="React" sub="For UI"></Subject> <Toc></Toc> <Content></Content> </div> ); } } export default App;
JavaScript
복사
React Developer Tools
import React, { Component } from 'react'; import TOC from './components/TOC' import Content from './components/Content' import Subject from './components/Subject' import './App.css' class App extends Component { constructor(props) { super(props); this.state = { subject: { title: "WEB", sub: "World Wide Web" }, contents: [ { id: 1, title: 'HTML', desc: 'HTML is HyperText...' }, { id: 2, title: 'CSS', desc: 'CSS is for design' }, { id: 3, title: 'JavaScript', desc: 'JavaScript is for interactive' } ] } } render() { return ( <div className="App"> <Subject title={this.state.subject.title} sub={this.state.subject.sub}> </Subject> <TOC data={this.state.contents}></TOC> <Content title="HTML" desc="HTML is HyperTextMarkup Language"></Content> </div> ); } } export default App;
JavaScript
복사
App.js
import React, { Component } from 'react'; class Toc extends Component { render() { var lists = [] var data = this.props.data var i = 0; while(i < data.length){ lists.push(<li key = {data[i].id}><a href = {"/content/" + data[i].id}>{data[i].title}</a></li>) i = i +1; } return ( <nav> <ul> {lists} </ul> </nav> ); } } export default Toc;
JavaScript
복사
Toc.js

이벤트, bind함수

import React, { Component } from 'react'; import TOC from './components/TOC' import Content from './components/Content' // import Subject from './components/Subject' import './App.css' class App extends Component { constructor(props) { super(props); this.state = { mode: 'read', subject: { title: "WEB", sub: "World Wide Web" }, welcome: { title: "Welcome", desc: "Hello, React!!" }, contents: [ { id: 1, title: 'HTML', desc: 'HTML is for information' }, { id: 2, title: 'CSS', desc: 'CSS is for design' }, { id: 3, title: 'JavaScript', desc: 'JavaScript is for interactive' } ] } } render() { console.log('App render') var _title, _desc = null if (this.state.mode === "welcome") { _title = this.state.welcome.title; _desc = this.state.welcome.desc; } else if (this.state.mode === 'read') { _title = this.state.contents[0].title; _desc = this.state.contents[0].desc; } return ( <div className="App"> {/* <Subject title={this.state.subject.title} sub={this.state.subject.sub}> </Subject> */} <header> <h1><a href = "/" onClick = {function(e){ console.log(e); e.preventDefault(); this.state.mode = 'welcome'; this.setState({ mode: 'welcome' }) }.bind(this)}>{this.state.subject.title}</a></h1> {this.props.sub} </header> <TOC data={this.state.contents}></TOC> <Content title={_title} desc={_desc}></Content> </div> );
JavaScript
복사
bind라는 거는 해당 함수에 대한 this를 argument로 바인딩해주는 거다.
일단 bind가 없으면 저 함수 안에 this값은 undefined인데, 왜 그렇냐??
어떤 클래스 내부에 선언된 함수는 클래스 내부에 선언된 것이 아니라, 클래스의 prototype에 선언된 것이기 때문.
클래스의 prototype은 undefined이기 때문에 저렇게 하는 거다.
그리고 this.state.mode = 'welcome'; 이런 식으로 하면 안된다.
컨스트럭터 내부에 컴포넌트를 전부다 설정했다면, 저 setState라는 함수를 통해서 바꿔야한다. 그래야만 render함수가 전부다 다시 로드 될 것. 왜냐하면 this.state.mode = 'welcome'이라고 짜면, 리액트 몰래 바꾼거다.
Props → 전달된 값을 함수 안에서 바꾸는 것은 불가하다. 즉 Read-Only이다.
State → State는 비동기적으로 바뀔 수 있다. this.setState라는 함수를 통해서 바꿀 수 있다.
상위 컴포넌트가 하위 컴포넌트로 값을 전달할 때는 Props
하위 컴포넌트가 상위 컴포넌트의 값을 바꾸고 싶다 → 이벤트를 통해서 한다.

리액트로 CRUD

Object.assign{}
var a = {name:'egoing'}; var b =Object.assign({},a); console.log(a,b,a===b); //false var a = [1]; var b = Array.from(a); console.log(a===b); //false
JavaScript
복사

배웠던 것 정리

Components

js파일로 Components들을 정의할 수 있다. 그리고 그렇게 정의된 컴포넌트들을 App.js라는 상위 div에서 붙였다 뗐다 할 수 있다.

Props

상위 컴포넌트에서 하위 컴포넌트로
상위 컴포넌트에서 하위 컴포넌트로 값을 던져줄 때 props를 사용한다

State

상위 컴포넌트에서 내부적으로 관리하고 있는 변수들이며, 하위 컴포넌트에서 상위 컴포넌트의 이 State변수들을 변경시킴으로써, 전체적으로 렌더링을 다시 시킨다.

Bind

클래스 안에 선언된 메소드,함수는 해당 컴포넌트(클래스)를 this로 가지고 있지 않는다. 이 함수의 this는 해당 클래스의 프로토타입을 this로 가지고 있고, 상속받은 클래스가 아닌 이상, 이 클래스의 프로토타입은 undefined이다.
따라서 해당 클래스 안에 있는 state들의 값을 바꾸고 싶다면, 해당 클래스를 바인딩 시켜줘야한다.

이벤트와 이벤트핸들러

상위 컴포넌트에 이벤트 핸들러를 작성하고, 하위 컴포넌트의 이벤트에서 상위 컴포넌트에서 props로 넘겨준 이벤트 핸들러를 붙인다.

추가로 궁금할 것?

immutable Js
URL만으로 페이지를 찾아올 수 없다.
리액트 라우터 → URL에 접근하면 적당한 컴포넌트를 로드할 수 있다.
create-react-app eject
개발환경을 수정할 수 있다.
redux : 리액트의 컴포넌트가 많아지면, 컴포넌트간 교류가 굉장히 빡세다.
중앙에 데이터 저장소 하나를 만들고, 모든 컴포넌트는 저장소와 직접 연결됨. 그것과 관련된 컴포넌트가 모두 변경된다.
react server side rendering
맨 처음에 html을 만들어서 뱉어준다.
react native
react와 같은 방법으로 앱을 만들 수 있다.

함수형 React, React Hook

UseState()함수를 사용하자
function FuncComp(props){ var numberState = useState(props.initNumber); var number = numberState[0]; var setNumber = numberState[1]; /* var dateState = useState((new Date()).toString()); var _date = dateState[0]; var setDate = dateState[1]; */ var [_date,setDate] = useState((new Date()).toString()); console.log(numberState); return ( <div className = "container"> <h2>function style componenet</h2> <p>Number: {number}</p> <p>Date: {_date}</p> <input type = "button" value = "random" onClick = { function(){ setNumber(Math.random()); } }></input> <input type = "button" value = "date" onClick = {function(){ setDate((new Date()).toString()); }}></input> </div> ); }
JavaScript
복사

LifeCycle

componentWillMount() → 컴포넌트가 생성됨
render() → 컴포넌트가 화면에 그려진다.
componenetDidMount() → 개발자가 구현함을 통해서 componenet 생성 이후에 뭔가를 할 수 있다.
—> 컴포넌트가 DOM에 나타나는 순간에 해야할 초기 작업들
컴포넌트가 퇴장할 때, 즉 청산할 때 → componentWillUnMount()를 활용한다.