'Javascript/React'에 해당되는 글 15건

  1. 2020.02.12 #3 React Event Handling
  2. 2020.02.12 #2 React Component
  3. 2020.02.12 #1 basic react
  4. 2020.02.12 #0 React intro
  5. 2019.09.03 webpack - resolve
  6. 2019.09.03 react-router
2020. 2. 12. 14:39

Event

웹 브라우저에서 DOM 요소와 상호작용하는 것을 이벤트라고 합니다.

예를들어 DOM 요소를 클릭하면 onClick 이벤트를 정의해 상호작용을 하게 됩니다.

 

리액트 이벤트 시스템 주의사항

  1. 이벤트 이름은 카멜 표기법으로 작성
  2. 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달
  3. DOM 요소에만 이벤트 설정할 수 있다
    • 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다. 단지 props를 전달해 줄 뿐.

 

클래스 컴포넌트의 이벤트 핸들링

- state와 메서드 활용

 

1. 이벤트 발생시 생성되는 e객체를 이용한 이벤트 핸들링

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    message: ' '
  };

  render() {
    return (
      <div>
        <input
          type="text"
          name="message"
          placeholde="input"
          value={this.state.message}
          onChange={e => {
            this.setState({ message: e.target.value });
          }}
        ></input>
        <br />
        <button
          onClick={() => {
            alert(this.state.message);
            this.setState({ message: ' ' });
          }}
        >
          reset
        </button>
      </div>
    );
  }
}

export default EventPractice;

 

 

2. 이벤트에 실행할 자바스크립트 코드 대신 함수 형태의 값 전달

=> 클래스에 메서드를 만들어 이벤트 리스너에 바인딩

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    message: ' '
  };

  handleChange = e => {
    this.setState({ message: e.target.value });
  };

  handleClick = () => {
    alert(this.state.message);
    this.setState({ message: ' ' });
  };

  render() {
    return (
      <div>
        <input
          type="text"
          name="message"
          placeholde="input"
          value={this.state.message}
          onChange={this.handleChange}
        ></input>
        <br />
        <button onClick={this.handleClick}>reset</button>
      </div>
    );
  }
}

export default EventPractice;

 

3. input 여러개 다루기 

=> e.target.name의 "값"을 키로 가지는 객체를 생성

=> ref = 'key' ;  { [ref] : 'value' } ref의 값을 key로 하는 객체 생성  { 'key' : 'value' }

=> 하나의 이벤트 핸들링 메서드로 여러 키값을 가지는 객체 생성가능

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    message: ' ',
    username: ' '
  };

  // ref = 'key' ;  { [ref] : 'value' } ref의 값을 key로 하는 객체 생성  { 'key' : 'value' }
  handleChange = e => {
    this.setState({ [e.target.name]: e.target.value });
  };

  handleClick = e => {
    alert(this.state.username + ' : ' + this.state.message);
    this.setState({ message: ' ' });
    this.setState({ username: ' ' });
  };

  render() {
    return (
      <div>
        <input
          type="text"
          name="username"
          placeholder="username"
          value={this.state.username}
          onChange={this.handleChange}
        ></input>
        <br />
        <input
          type="text"
          name="message"
          placeholde="message"
          value={this.state.message}
          onChange={this.handleChange}
        ></input>
        <br />
        <button onClick={this.handleClick}>reset</button>
        <hr />
      </div>
    );
  }
}

export default EventPractice;

 

함수형 컴포넌트의 이벤트 핸들링

- useState 활용

import React, { useState } from 'react';

const EventPractice = () => {
  const [form, setForm] = useState({
    username: ' ',
    message: ' '
  });

  const { username, message } = form;

  const handleChange = e => {
    const nextForm = {
      ...form,
      [e.target.name]: e.target.value
    };
    setForm(nextForm);
  };

  const handleClick = e => {
    alert(username + ' : ' + message);
    setForm({
      username: ' ',
      message: ' '
    });
  };

  return (
    <div>
      <input
        type="text"
        name="username"
        value={username}
        onChange={handleChange}
      ></input>
      <br />
      <input
        type="text"
        name="message"
        value={message}
        onChange={handleChange}
      ></input>
      <br />
      <button onClick={handleClick}>reset</button>
    </div>
  );
};

export default EventPractice;

 

 

 

 

'Javascript > React' 카테고리의 다른 글

#5 React Component Lifecycle  (0) 2020.02.13
#4 Component 반복  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
Posted by yongminLEE
2020. 2. 12. 14:38

 

컴포넌트 종류

  1. 클래스형 컴포넌트
    • state 기능 사용가능
    • 라이프사이클 기능 사용가능
    • 임의의 메서드 정의 가능
    • constructor 작성시 반드시 super(props); 메서드를 호출하여 리액트의 Component 클래스가 지닌 생성자를 호출
    • render 함수가 반드시 있어야 하고, 그 안에서 보여 주어야 할 JSX를 반환해야 한다
  2. 함수형 컴포넌트
    • 클래스형 컴포넌트 보다 메모리 소모가 적음
    • state, 라이프사이클 대신 hooks 사용

 

Props

  • properties의 줄인 표현으로 컴포넌트 속성을 읽을 때 사용하는 요소
  • 해당 컴포넌트의 부모 컴포넌트에서 설정하며 컴포넌트 자신은 해당 props를 "읽기전용"으로 사용
  • defaultProps : 부모컴포넌트에서 따로 props 값을 설정하지 않을 때 보여지는 기본값
  • props.children : 태그 사이의 내용
  • propTypes : 컴포넌트의 props의 타입값 지정. 지정한 타입과 일치하지 않으면 콘솔창에 에러 출력
  • isRequired : 필수 props 지정
  • 클래스형 컴포넌트에서 props 사용 : render함수에서 this.props로 조회

 

State

  • 컴포넌트 내부에서 바뀔 수 있는 값
  • 클래스형 컴포넌트의 state
    1. state는 객체형식
    2. state 초기화
      1. 클래스의 constructor에서 초기화
      2. 클래스 내부에서 바로 초기화 state = { ... } 
    3. render 함수에서 state를 조회할때는 this.state
    4. this.setState 메서드로 state값 변경 : setState의 인자로 전달해준 객체/함수로 state값 변경 
  • 함수형 컴포넌트의 useState( )
    1. useState 함수 호출시 인자로 상태의 초깃값을 전달, 이때 반드시 객체형식이 아니어도 숫자, 문자열, 배열 모두 가능
    2. useState( ) 호출시 배열 반환
      1. 첫번째 원소 : 현재상태
      2. 두번째 원소 : 상태를 바꿔주는 함수
    3. 배열 비구조화 할당 (array destructuring assignment)을 통해 useState( ) 가 반환하는 배열의 원소들을 쉽게 바인딩 가능
  • 클래스형 컴포넌트와 함수형 컴포넌트 모두 state 값을 변경할때는 setter를 이용

 

 

 

'Javascript > React' 카테고리의 다른 글

#4 Component 반복  (0) 2020.02.12
#3 React Event Handling  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
webpack - resolve  (0) 2019.09.03
Posted by yongminLEE
2020. 2. 12. 14:38

React란?

  • 어플리케이션 구조 중에서 View만을 담당하는 라이브러리
  • React is a JavaScript library for building user interfaces
  • 어떤 데이터가 변할 때마다 어떤 변화를 줄지 고민하지 않고 그냥 기존 뷰를 날려 버리고 처음부터 새로운 데이터를 가지고 render함수를 호출하여 새로 렌더링 함으로써 어플리케이션의 구조를 간단화
    -> render 함수가 반환하는 결과를 곧바로 DOM에 반영하지 않고 이전에 render 함수가 만들었던 컴포넌트 정보와 현재 render 함수가 만든 컴포넌트 정보를 비교
    -> 둘의 차이를 알아내 최소한의 연산으로 DOM 트리 업데이트

 

React 특징

  1. VirtualDOM을 사용한 화면 조작
    • 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링
    • 이전 Virtual DOM에 있던 내용과 현재 내용을 ‘diffing’ 알고리즘을 사용하여 변화를 확인
    • 바뀐 부분만 실제 DOM에 적용
    • 리액트와 virtual dom이 제공하는 것은 "업데이트 처리의 간결성"
      => 지속적으로 데이터가 변화하는 대규모 어플리케이션에 사용하는것이 적절
  2. 컴포넌트(Components)와 단방향 데이트 흐름(Unidirectional data flow)
    • React는 Component로 구성, 개발 할 때 컴포넌트 단위로 고려하는 것이 좋음
    • React에선 데이터가 단방향으로 전송 ->  데이터 추적 및 디버깅이 상대적으로 쉬움. 이러한 특징을 살려서 Flux 패턴을 사용한 Redux라이브러리를 많이 활용함

 

Module Bundler

  • 각각의 모듈들에 대해 의존성 관계를 파악한 후 모듈들을 하나의 파일로 그룹핑하는 소프트웨어
  • 브라우저에는 모듈을 불러오는 기능이 없으므로 브라우저에 실행 가능한 자바스크립트 파일을 만들기 위해 번들러를 사용
  • 대표적인 번들러 : webpack, parcel, ...
  • 웹팩 로더 : svg, css 파일들을 불러오는 웹팩의 기능
    • ex) css-loader : css파일을 불러옴
    • babel-loader : 자바스크립트 파일들을 불러오면서 최신 자바스크립트 문법을 구버전 웹 브라우저에서도 실행 가능하도록 ES5 문법으로 변환

 

JSX

  • JSX it is a syntax extension to JavaScript
  • JSX 문법
    1. 감싸인 요소 : 컴포넌트에 여러 요소가 있다면 반드시 부모요소 하나로 감싸야 한다 => <div></div> or <></>
    2. 자바스크립트 표현식 : JSX 내부에서 JS 코드를 { } 로 감싼다.
    3. 조건부연산자 : JSX 내부 자바스크립트 표현식에 if문을 사용할 수 없으므로 조건부연산자(삼항연산자)를 사용
    4. clssName : class 속성 대신 className 속성 설정
    5. 주석 : JSX 내부에서는 {/* 주석을 이렇게 작성 해야한다 */}

 

Components

  • Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.
  • Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. 

 

Props

  • React passes JSX attributes to a user-defined component as a single object. 
    We call this object "props".
  • 컴포넌트 속성 설정및 부모 컴포넌트의 데이터를 자식에게 전달할 때 사용
  • props값은 해당 부모 컴포넌트에서만 설정 가능


 State

  • State는 컴포넌트 내부에서 읽기(read)와 변경(update) 가능한 데이터
  • this.setState() 메서드를 사용하여 State값을 update
  • State값을 변경해서 화면(view)이 변경되면 render()가 자동으로 재실행

 

Life Cycle (React v16.3 이후)

  • Mounting
     : constructor  ->  getDerivedStateFromProps  ->  render  ->  componentDidMount
  • Updating - New props
     : getDerivedStateFromProps   -> shouldComponentUpdate -> render  -> getSnapshotBeforeUpdate -> componentDidUpdate
  • UPdating - setState()
    : shouldComponentUpdate -> render  -> getSnapshotBeforeUpdate -> componentDidUpdate
  • Unmounting
    : componentWillUnmount

 

FLUX 패턴/아키텍처

  • Action –> Dispatcher –> Store –> View 구조를 통해 데이터를 전달, 업데이트 하는 패턴
  • View에서 Dispatcher로 Action을 보낼 수 있으며, Dispatcher는 작업이 중첩되지 않도록 Action을 스케쥴링 (사실상 대기)
  • FLUX 패턴/아키텍처를 좀 더 유연하게 사용할 수 있도록 ‘Redux’라는 라이브러리를 많이 사용

'Javascript > React' 카테고리의 다른 글

#3 React Event Handling  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
webpack - resolve  (0) 2019.09.03
react-router  (0) 2019.09.03
Posted by yongminLEE
2020. 2. 12. 14:38

 

  1. basic react
  2. react component
  3. event handling
  4. component 반복
  5. lifecycle
  6. hooks
  7. component styling
  8. todo project
  9. immer
  10. react-router, SPA
  11. Asynchrony
  12. redux
  13. todo project + redux
  14. middleware
  15. backend : express + mongodb
  16. MEMOAPP project : https://velopert.com/tag/reactcodelab

참고

- 리액트를 다루는 기술

- 인프런 : https://www.inflearn.com/course/react-%EA%B0%95%EC%A2%8C-velopert#description 

 

'Javascript > React' 카테고리의 다른 글

#3 React Event Handling  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
webpack - resolve  (0) 2019.09.03
react-router  (0) 2019.09.03
Posted by yongminLEE
2019. 9. 3. 13:39

Webpack에서 Resolve 설정을 추가해주면 React 프로젝트의 루트디렉토리를 설정합니다.

// webpack.config.js
// webpack.dev.config.js
var path = require('path');
/* .. 코드 생략 .. */
resolve: {
    root: path.resolve('./src')
}

이렇게하면 코드에서 import 시 path에서 간단하게 접근할 수 있게 해줍니다.

 

resolve 셋팅 전

import Home from './components/Home';
// or
import Home from './../components/Home';

 

resolve 셋팅 후

import Home from 'components/Home';

'Javascript > React' 카테고리의 다른 글

#3 React Event Handling  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
react-router  (0) 2019.09.03
Posted by yongminLEE
2019. 9. 3. 13:37

1. previous page VS SPA

- previous page

: 유저가 요청할 때마다 페이지를 새로고침하며, 페이지를 로딩할 때마다 서버에서 리소를 전달받아 해석한 후 렌더링. HTML파일 또는 템플릿 엔진(ex: pug)등을 사용해서 뷰를 어떻게 보일지도 서버에서 담당

=> 단점 : 서버에서 렌더링을 담당하므로 그만큼 서버자원 소모->불필요한 트래픽낭비

=> 해결 : 리액트와 같은 라이브러리나 프레임워크를 사용하여 뷰 렌더링을 유저의 웹브라우저가 담당하도록하고, app을 우선 웹 브라우저에 로드시킨 후 필요한 데이터만 전달

 

- SPA

: 서버에서 제공하는 페이지가 하나이지만, 웹브라우저에서 나머지 페이지들을 정의. 다른 페이지로 이동할 때는 서버에 새로운 페이지를 요청하는 것이 아니라, 새 페이지에서 필요한 데이터만 받아 와 그에 따라 웹브라우저가 다른 종류의 뷰를 만든다.

 

- routing

: 주소에 따라 다른 뷰를 보여주는 것

 

- react-router

: 서드 파티 라이브러리로, 페이지 주소를 변경했을 때 주소에 따라 다른 컴포넌트를 렌더링하고, 주소정보를 컴포넌트의 props로 전달해서 컴포넌트 단에서 주소 상태에 따라 다른 작업을 하도록 설정가능

 

2. react-router 라이브러리를 이용한 SPA 개발

2-1. 프로젝트 생성및 컴포넌트 준비

$ create-react-app react-router-project
$ yarn add creat-router-dom

 

2-2. 컴포넌트 준비

//src/App.js
import React from 'react';

function App() {
  return (
    <div className="App">
    	react-router
    </div>
  );
}

export default App;

 

//src/Root.js
import React from 'react';
import App from './App';

//BrowserRouter : HTML$의 history api를 사용하여 새로고침하지 않고도 페이지 주소를 교체
import {BrowserRouter} from 'react-router-dom'; 

const Root = () => {
    return (
        <BrowserRouter> 
            <App />
        </BrowserRouter>
    );
};

export default Root;

 

//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Root from './Root';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<Root />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

 

2-3. 기본 라우트 설정

//src/pages/Home.js
import React from 'react';

const Home = () => {
    return (
        <div>
            <h1>HOME</h1>
        </div>
    );
};

export default Home;

 

//src/pages/About.js
import React from 'react';

const About = () => {
    return (
        <div>
            <p>this is about page</p>
        </div>
    );
};

export default About;

 

export {default as Home} from './Home';
export {default as About} from './About';

 

//src/App.js
import React from 'react';

// router
import {Route} from 'react-router-dom';
import {Home, About} from './pages';

function App() {
  return (
    <div className="App">
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
    </div>
  );
}

export default App;

 

2-4. 라우트 파라미터와 쿼리 읽기

//src/App.js
import React from 'react';

// router
import {Route} from 'react-router-dom';
import {Home, About} from './pages';

function App() {
  return (
    <div className="App">
      <Route exact path="/" component={Home} />
      <Route path="/about/:name?" component={About} /> 
    </div>
  );
}

export default App;

- params를 지정할 때는 :key형식으로 설정

- :name값을 선택적으로 입력받을 수 있게 뒷부분에 ?를 입력

//src/pages/About.js

import React from 'react';
import queryString from 'query-string';

const About = ({location, match}) => {
    const query = queryString.parse(location.search);
    const {color} = query //const color = query.color;

    return (
        <div>
            <h1 style={{color}}>About</h1>
            <p>this is about page</p>
            <p>params : {match.params.name}</p>
        </div>
    );
};

export default About;

- query-string 라이브러리는 문자열로 된 쿼리를 객체 형태로 파싱

 

2-5. 라우터이동 : Link컴포넌트, NavLink 컴포넌트, 자바스크립트에서 라우팅

//src/components/Menu.js
import React from 'react';
import {Link} from 'react-router-dom';
import {NavLink} from 'react-router-dom';

const Menu = () => {
    const activeStyle = {
        color:'green',
        fontSize:'2rem'
    }

    return (
        <div>
            <ul>
                <li><Link to="/">HOME</Link></li>
                <li><Link to="/about">ABOUT</Link></li>
                <li><Link to="/about/react">ABOUT REACT</Link></li>
                <li><a href="/about">ABOUT with 새로고칭</a></li>
                <li><a href="/about/react">ABOUT REACT with 새로고칭</a></li>
                <li><NavLink exact to="/" activeStyle={activeStyle}>HOME</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>ABOUT</NavLink></li>
                <li><NavLink exact to="/about/react" activeStyle={activeStyle}>ABOUT REACT</NavLink></li>
            </ul>
        </div>
    )
};

export default Menu;

- <a href>...</a> : 페이지를 새로고침하면서 로딩

- Link 컴포넌트 : 페이지를 새로고침하여 불러오지 않고, 주소 창 상태를 변경하고 원하는 라우트로 화면을 전환

- NavLink 컴포넌트 : 현재주소와 해당 컴포넌트의 목적지 주소가 일치하면 특정스타일 또는 클래스 지정 가능

 

//src/pages/Home.js
import React from 'react';

const Home = ({history}) => {
    return (
        <div>
            <h1>HOME</h1>
            <button onClick={()=>{history.push('./about/JS')}}>JS로 라우팅</button>
        </div>
    );
};

export default Home;

 

2-6. 서브라우터 : 라우트 안의 라우트 

//src/components/Menu.js
import React from 'react';
import {NavLink} from 'react-router-dom';

const Menu = () => {
    const activeStyle = {
        color:'green',
        fontSize:'2rem'
    }

    return (
        <div>
            <ul>
                <li><NavLink exact to="/" activeStyle={activeStyle}>HOME</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>ABOUT</NavLink></li>
                <li><NavLink exact to="/about/react" activeStyle={activeStyle}>ABOUT REACT</NavLink></li>
                <li><NavLink exact to="/postList" activeStyle={activeStyle}>POST LIST</NavLink></li>
            </ul>
        </div>
    )
};

export default Menu;

 

//src/App.js
import React from 'react';
import Menu from './components/Menu';

// router
import {Route} from 'react-router-dom';
import {Home, About, PostList} from './pages';

function App() {
  return (
    <div className="App">
      <Menu />
      <Route exact path="/" component={Home} />
      <Route path="/about/:name?" component={About} />
      <Route path="/postList" component={PostList} />
    </div>
  );
}

export default App;

 

//src/pages/PostList.js
import React from 'react';
import { Post } from 'pages';
import { Link, Route } from 'react-router-dom';

const PostList = ({ match }) => {
    return (
        <div>
            <h2>POST LIST</h2>
            <ul>
                <li><Link to={`${match.url}/1`}>POST #1</Link></li>
                <li><Link to={`${match.url}/2`}>POST #2</Link></li>
                <li><Link to={`${match.url}/3`}>POST #3</Link></li>
            </ul>
            <Route exact path={match.url} render={() => (<p>choose a post</p>)} />
            <Route exact path={`${match.url}/:id`} component={Post} />
        </div>
    );
};

export default PostList;

 

//src/pages/Post.js
import React from 'react';

const Post = ({match}) => {

    return (
        <div>
            <p>포스트 id : {match.params.id}</p>
        </div>
    );
};

export default Post;

 

//src/pages/index.js
export {default as Home} from './Home';
export {default as About} from './About';
export {default as Post} from './Post';
export {default as PostList} from './PostList';

 

2-7. 라우트로 사용된 컴포넌트가 전달받는 props : location, match, history

 

- location.pathname 은 현재 브라우저상의 위치를 알려줍니다. 이 값은 어떤 라우트에서 렌더링하던 동일합니다.

- match 관련은 설정한 Route 와 직접적으로 관계된 값만 보여줍니다.

  • Posts 를 보여주는 라우트에선 :id 값을 설정하지 않았으니 path 와 url 이 둘다 /posts 입니다.
  • Post 를 보여주는 라우트에선 path 의 경우엔 라우트에서 설정한 path 값이 그대로 나타납니다. url 의 경우엔 :id 부분에 값이 들어간 상태로 나타납니다.- histroy는 현재 라우터를 조작할 때 사용

'Javascript > React' 카테고리의 다른 글

#3 React Event Handling  (0) 2020.02.12
#2 React Component  (0) 2020.02.12
#1 basic react  (0) 2020.02.12
#0 React intro  (0) 2020.02.12
webpack - resolve  (0) 2019.09.03
Posted by yongminLEE