반응형

Union : 값이 허용된 타입을 두개 이상의 가능한 타입으로 확장하는 것

let physicist = Math.random() > 0.5 ? "TEST" : 100;

실제 위와 같은 코드에서는 아래와 같이 판단한다.

Narrowing : 값이 허용된 타입이 하나 이상의 가능한 타입이 되지 않도록 좁히는것

let animal: number | string;
animal = 'tiger';

number 와 string 으로 선언했지만 값 할당을 통해서 string 타입으로 확인되었기 때문에 string 관련 메소드만 사용 가능 하다.

아래와 같이 조건문을 통해서도 타입이 결정될수 있다.

let physicist = Math.random() > 0.5 ? "TEST" : 100;

typeof physicist === "string" ? physicist.toUpperCase() : physicist.toFixed();

 

728x90
반응형
반응형

html 태그로 표현되어있는 문법을 createElement 로 변환해준다.

const vdom = <p>
  <h1>헤더</h1>
  <ul>
    <li style="color:red">첫번째</li>
    <li style="color:blue">두번째</li>
  </ul>
</p>

위에 있는 코드가 아래와 같이 변환이 된다.

"use strict";

const vdom = /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("h1", null, "\uD5E4\uB354"), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", {
  style: "color:red"
}, "\uCCAB\uBC88\uC9F8"), /*#__PURE__*/React.createElement("li", {
  style: "color:blue"
}, "\uB450\uBC88\uC9F8")));

출처 : https://babeljs.io/ 에서 변환함.

왜 저렇게 변환이 필요한가?? 

// app.js
const vdom = createElement(
  "p",
  {},
  createElement("h1", {}, "헤더"),
  createElement(
    "ul",
    {},
    createElement("li", { style: "color:red" }, "첫번째"),
    createElement("li", { style: "color:blue" }, "두번째")    
  )
);

// react.js
export function createElement(tag, props, ...children) {
  props = props || {}
  return {
    tag,
    props,
    children,
  };
}

JSX 를 사용하지 않으면 위와같이 코드를 작성해줘야 한다. 하지만 위보다는 html 태그 구조가 눈에 더 잘 들어온다.

한가지 더 기본적으로 JSX 가 변환을 할때에 메소드를 보면 React.createElement를 사용한다. 하지만 위에 작성된 코드에서는 createElement를 사용하고 있다. 이걸 변경해주려면 다음과 같이 표시해 주면된다. 변환된 코드는 아래와 같다.

/* @jsx createElement */
// app.js
const vdom = createElement(
  "p",
  {},
  createElement("h1", {}, "헤더"),
  createElement(
    "ul",
    {},
    createElement("li", { style: "color:red" }, "첫번째"),
    createElement("li", { style: "color:blue" }, "두번째")    
  )
);

실제로 babel 사이트에서 변환된 것을 봐도 변경된 것을 알수 있다.

"use strict";

// app.js
const vdom = createElement("p", {}, createElement("h1", {}, "헤더"), createElement("ul", {}, createElement("li", {
  style: "color:red"
}, "첫번째"), createElement("li", {
  style: "color:blue"
}, "두번째")));

 

728x90
반응형
반응형

개요

  • node.js 문법을 써야 한다.
  • entry 에 있는 명령어를 읽어서 변환과정을 거쳐서 output 으로 전달함.
  • entry -> module -> plugin -> output 으로 전달됨
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
  mode: "development",
  entry: "./src/app.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  devServer: {
    compress: true,
    port: 9999,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"]
          },
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "2.3 setup webpack & babel",
      template: "index.html"
    }),
  ],
};
  • loader
    • 특정 모듈을 변환하는대 사용한다.
    • .js 파일을 babel-loader 를 사용해서 변환해라. /node_modules/ 폴더는 제외하고!!
  • plugin
    • 플러그인을 사용하면 번들을 최적화 하거나 애셋을 관리하고 환경변수등을 주입하는게 가능하다.
    • require 를 통해서 플러그인을 요청한다.
    • 다른 목적을 위해 플러그인을 여러번 사용할수 있기 때문에 new 를 사용해서 인스턴스를 만들어야 한다.

참고

https://webpack.kr/concepts/

728x90
반응형
반응형

여러가지 배열 연산 형태 
함수 형태나 쓰임이 많다보니 코드를 봤을때 대체 무슨 의미인지 파악이 어려워서 공부하다가 형태를 기억하면 좋을것 같아서 남겨놔봤다. 

type Book = {
    title: string;
    copyright?: string;
    author?: string;
};

const books: string[] = [
    "헨리 6세",
    "리처드 3세",
    "실수 연발",
    "말괄량이 길들이기",
    "헨리 8세",
];

// foreach 문
books.forEach((book: string, idx: number, books: string[]) => {
    console.log(book, idx);
})

// map 사용1
const bookObject: Book[] = books.map((book:string) =>{
    return {
        title:book,
        author: undefined,
    };
});

console.log(bookObject); 
/*  [ { author: undefined, title: '헨리 6세' },
  { author: undefined, title: '리처드 3세' },
  { author: undefined, title: '실수 연발' },
  { author: undefined, title: '말괄량이 길들이기' },
  { author: undefined, title: '헨리 8세' } ] */

// map 사용2
const ShakespeareOneBooks: Book[] = books.map((book: string) => ({
    title:book
}))
.map((book: Book) => ({
    ...book,
    author: "William Shakespeare"
}));

console.log(ShakespeareOneBooks);

// map 사용2 와 형태가 다르지만 동일 동작임.
const bookTitleToBookObject = (book: string) => ({title:book});
const makeAuthor = (name: string) => (book: Book) => ({
    ...book,
    author: name
});

const shakespeareTwoBooks: Book[] = books
.map(bookTitleToBookObject)
.map(makeAuthor("William Shakespeare"));

console.log(shakespeareTwoBooks);

// filter
const henry: Book[] = shakespeareTwoBooks.filter((book: Book) =>
    book.title.includes("헨리")
);

console.log(henry);

// reduce
// reduce 는 함수와 초기화 값을 넘겨줌
// 함수에는 2개의 인자를 넘겨주는데 첫번째에는 초기값, 두번째는 배열의 값을 넘겨줌
// 함수가 반복되면서 첫번째 인자에는 다시 결과값을 계속 넣어주게됨.
// 0, 10 -> 10, 5 -> 15, 3 .. 이런 형태로 값이 들어감.
const someNumbers: number[] = [10,5,3,14,56];
const someNumber = someNumbers.reduce((a:number, b:number) => a + b , 0)

console.log(someNumber);	// 88

type SomeObject = {
    [key: string]: string | number;
};

// reduce object
const someObjects: SomeObject[] = [
    { border: "none"},
    { fontSize: 24},
    {className: "box sm-box"},
];

const someObject: SomeObject = someObjects.reduce(
    (a: SomeObject, b: SomeObject) => ({...a, ...b}),
    {}
);
console.log(someObject) // { border: 'none', className: 'box sm-box', fontSize: 24}

(출처 : 패스트 캠퍼스 - 김민태의 프론트엔드 아카데미 : https://fastcampus.co.kr/dev_academy_kmt1)

728x90
반응형
반응형

매일 봐도 까먹는 자바스크립트 함수형태들...

function fn(x){
	return x + 100;
}

const result = fn(10);

# 이름없는 함수
const fn2 = function (){
	return 100;
};

fn2();

# 즉시 실행 함수
(function(){
	console.log('test')
})();

# Arrow 함수
const fn3 = () => {
	return 100;
}

const fn4 = () => 100;

# Generator 함수
# 최초 호출하면 함수가 실행되지 않고 실행 준비상태로 만듬. 
# 그리고 객체를 반환하며 이 객체에는 함수를 실행할 도구가 담겨져 있다.
# 도구를 이용해서 함수를 실행하고 멈추고 할수 있음.
function* fn5(){
	yield 10; 
	yield 20;
	return 30;
}

const g = fn5();
g.next();  // {value: 10, done: false}
g.next();  // {value: 20, done: false}
g.next();  // {value: 30, done: true}


# 비동기 함수
async function fn6(){
    
}

 

 

728x90
반응형
반응형

React 에서 Key 가 필요한 이유

  • Map 사용시 고유한 Key 가 필요하다.
  • React 는 상태를 메모리에 저장하고 있다가 변경된 부분만 렌더링 한다.
  • Key 값이 없으면 모든 데이터를 비교해야 하지만 Key 가 있으면 Key만 비교하면 된다.
  • <ul>
      {props.users.map((user) => (
        <li key={user.id}>
          {user.username} ({user.age} years old)
        </li>
      ))}
    </ul>

Map 에서 index 를 Key로 하면 안되는 이유

  • 0번의 index 가 삭제되면 React 가 변경을 감지하여 리렌더링 되고 0번 부터 다시 매핑한다.
  • 1번 인덱스가 0번으로 매핑이 된다.
  • 결론적으로 인덱스가 추가되거나 삭제되면 값이 바뀌기 때문에 index 를 key 로 사용하는것은 안좋다.
728x90
반응형
반응형
  • 값과 함수를 반환한다.
  • 함수는 값을 변화시킨후 컴포넌트를 리렌더링한다
  • 여러개의 state 를 정의할 수도 있고 object로 관리할수도 있다.
    const [enteredTitle, setEnteredTitle] = useState('');
    const [enteredAmount, setEnteredAmount] = useState(0);
    const [enteredDate, setEnteredDate] = useState();
    const [userInput, setUserInput] = useState({
      enteredTitle: '',
      enteredAmount: 0,
      enteredDate: ''
    })
    • 주의 할 점은 update 시 object에 있는 일부 키만 업데이트 한다면 다른 키들이 사라진다.
    • 아래와 같이 enteredTitle 키만 정의할 경우 나머지 키는 사라진다. (merge 하지 않는다)
      const titleChangeHandlerNew = (event) => {
        setUserInput.enteredTitle = event.target.value
      };
    • 수동으로 복사가 필요하다. 기본값을 복사한후 오버라이드 한다.
      const titleChangeHandlerNew = (event) => {
        ...userInput,
        setUserInput.enteredTitle = event.target.value
      };
      • 위 방법에서는 문제가 발생할 수 있다.
      • 리액트가 상태업데이트 바로 실행하지 않는다.
      • 따라서 동시에 많은 상태를 업데이트 할 경우 최신값을 잘못 가져올수 있다.
      • 따라서 다음과 같이 사용하는게 더 낫다. (스냅샷을 이용한다)
        const titleChangeHandlerNew2 = (event) => {
        setUserInput((prevState) => {
          return {
            ...prevState,
            enteredTitle: event.target.value
          }
        });
        };
  • useState 를 사용해서 set을 했는데 화면에서 안바뀔 경우
    • 사실 변경이 안된것이 아니라 화면만 전환이 안된것이다. (input 같은 경우)
    • 이럴때에는 value 에 입력 값을 바인딩 해준다.
728x90
반응형
반응형

edX사이트에서 Introduction to ReactJS 강의를 들으면서 정리한 내용입니다. 

 

2018/04/18 - [Development/React] - edX - Introduction to ReactJS Module1 내용정리

 

 

Class Components

- Class Component

Class Component 는 Functional Component 와 다르게 React Component 가 라이프사이클 메소드(Life Cycle method) 와 상태(state) 를 가질수 있도록 해준다. Class Component는 this.state, this.props 를 가지고 있다. 

 

1
2
3
4
5
class Welcome extends React.Component{
    render(){
        return <h1>Hello World!</h1>
    }
}
cs

 

- Render()

render() 메소드는 Class Component 에서 React Element를 리턴할때 사용된다.

 

- Adding properties to Class Components

Class Component의 property는 this.props 를 통해서 접근가능하다. 

 

1
2
3
4
5
class Welcome extends React.Component{
    render(){
        return <h1>Message: {this.props.message}</h1>
    }
}
cs

 

1
<Welcome message="Hello World!"/>
cs

 

State

- Constructor(props)

constructor() 메소드는 React Component 가 mount 되기 전에 호출되며 component의 기본 상태를 설정하는데 사용된다. 

constructor() 메소드 시작에 super(props)를 호출하는것은 중요하다. 안할 경우 this.props 가 정상적으로 동작하지 않을 수 있다. 

constructor() 메소드의 첫번째 파라메터는 component에 전달되는 속성을 나타낸다. 

 

1
2
3
4
5
6
7
8
class Counter extends React.Component{
    constructor(props){
        super(props)
    }
    render(){
        return <div>Hello World!</div>
    }
}
cs

 

- Adding an initial state to Class Component

Class Component 의 state 는 반드시 object 형태로 선언되어야 한다. 

 

1
2
3
4
5
6
7
8
9
class Counter extends React.Component{
    constructor(props){
        super(props)
        this.state = {foo:123,bar:456}
    }
    render(){
        return <div>foo:{this.state.foo} bar:{this.state.bar}</div>
    }
}
cs

 

- Updating State

setState(updater, [callback]) 을 통해서 상태 업데이트가 가능하다. 상태를 업데이트 하는 것은 비동기식이기 때문에 옵션으로 callback 메소드를 호출하게 할수있다. callback 메소드는 업데이트가 완료되면 호출된다. 

setState 메소드는 component life cycle의 updating 단계를 시작하는 트리거가된다. 이것 때문에 sshouldComponentUpdate() 메소드가 false를 리턴하지 않으면 component가 다시 렌더링 된다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Counter extends React.Component{
    constructor(props){
        super(props)
        //initial state set up
        this.state = {message:"initial message"}
    }
    componentDidMount(){
        //updating state
        this.setState({message:"new message"})
    }
    render(){
        return <div>Message:{this.state.message}</div>
    }
}
cs

 

- Updating state based on previous state

setState() 메소드는 Component의 상태를 즉시 업데이트 하지 않고 큐에 넣어둔 후 나중에 진행된다. 렌더링을 좀더 효율적으로 하기위해서 batch형태로 업데이트 한다. 

아래 소스에서 setState 메소드를 여러번 호출하지만 state value 는 1만 증가한다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Counter extends React.Component{
    constructor(props){
        super(props)
        //initial state set up
        this.state = {value:0}
    }
    componentDidMount(){
        //updating state
        this.setState({value:this.state.value+1})
        this.setState({value:this.state.value+1})
        this.setState({value:this.state.value+1})
        this.setState({value:this.state.value+1})
    }
    render(){
        return <div>Message:{this.state.message}</div>
    }
}
cs

 

setState() 메소드는 첫번재 파라메터로 메소드를 사용할수 있으며 기존 상태와 설정을 넘겨준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Counter extends React.Component{
    constructor(props){
        super(props)
        //initial state set up
        this.state = {message:"initial message"}
    }
    componentDidMount()
        //updating state
        this.setState((prevState, props) => {
            return {message: prevState.message + '!'}
        })
    }
    render(){
        return <div>Message:{this.state.message}</div>
    }
}
cs

 

- State is not mutable

State 는 오직 읽기만 가능하기 때문에 임의로 변경해서는 안된다. 

 

Life Cycle Methods

- Mounting Phase Methods

mounting 단계는 component가 생성되거나 DOM 에 렌더링할때 시작된다. 

  • constructor(props) : component 가 처음 초기화할때 오직 한번만 호출된다.
  • componentWillMount() : component 가 mount 하려고 할때 호출된다.
  • render() : component가 렌더링 할때 호출된다.
  • componentDidMount() : component 가 mount 된 후에 호출된다.

- Updating Phase Methods

updating 단계는 component state 또는 properties 가 변경될때 시작된다.

  • componentWillReceiveProps(nextProps) : component 가 update  되고 새로운 props를 받았을때 호출된다.
  • shouldComponentUpdate(nextProps, nextState) : 새로은 props는 받고 update 하려고 할때 호출된다. 이 메소드가 false 이면 componentWillUpdate(), render(),  componentDidUpdate() 는 실행되지 않는다.
  • componentWillUpdate(nextProps, nextState) : update 될때 호출된다. 
  • render()
  • componentDidUpdate(prevProps, prevState) : update  끝나고 호출된다.

- Unmounting Phase Methods

unmounting 단계는 component 가 DOM 에서 제거될때 시작된다. 

  • componentWillUnmount() : component 가 unmount 되고 즉시 호출된다. 

 

Event Handlers

- Adding Event Handlers

React 와 HTML 에서의 이벤트 핸들러 차이

  • React 에서는 JSX {} 을 사용해서 정의한다.
  • React 에서는 이벤트 이름을 쓸때 camelCase 를 사용한다. 
1
2
3
4
5
React
<button onClick = {clickHandler} >Click Me</button>
 
HTML
<button onclick = "clickHandler()" >Click Me</button>
cs

 

- Binding Event Handlers to Claas Component

이벤트 핸들러는 Class Component 내부에 정의 해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Counter extends React.Component{
    constructor(props){
        super(props)
        this.state = {count:0}
        //binding is necessary to make `this` point to the correct object
        this.clickHandler = this.clickHandler.bind(this)
    }
    clickHandler(){
      //increments the count of the state
      this.setState((prevState,props) => {
        return {count: prevState.count + 1}
      })
    }
    render(){
        //renders a button that displays the state count
        return <button onClick = {this.clickHandler}>{this.state.count}</button>
    }
}
 
ReactDOM.render(
  <Counter/>,
  document.getElementById("root")
)
cs

 

 

728x90
반응형
반응형

edX사이트에서 Introduction to ReactJS 강의를 들으면서 내용을 정리해봤다.


What is ReactJS?

ReactJS 는 상태에 따라서 View 레이어를 만들어 주는 라이브러리이다.

React Compnents는 Virtual DOM 을 생성한다. ReactCompnent의 상태가 변경되면 새로운 Virtual DOM을 생성하고 차이점을 분석한다. 그리고 효과적인 방법으로 HTML  DOM 에 반영한다.


Rendering Elements

- React Elements

React Elements 는 DOM 노드에 표현되는 Object 이다. JSX를 사용해서 syntax를 작성한다. React Elements와 React Components는 다르다. React Elements를  DOM 에 표현하기 위헤서는 ReactDOM.render() 메소드를 사용해야 한다.


- ReactDOM.render()

ReactDOM.render() 메소드는 HTML DOM의 특정 부분에 React Elements를  렌더링하는데 사용된다. 대부분 React 어플리케이션에는 한개의 root node 가 있고 그 안에 렌더링 되는데 root node가 여러개 있을수도 있다.


1
<div id="root"></div>
cs


1
2
3
4
ReactDOM.render(
        <h1>Hello World!</h1>,
        document.getElementById("root")
)
cs


JSX

- What is JSX?

JSX는 Javascript의 syntax 를 확장한 것으로 HTML 태그를 사용해서 Javascript안에 React Elements를 작성할수 있게 해준다.


1
var element = <h1>Hello World!</h1>
cs


- Using JSX with JavaScript Expressions

Curly braces ({}) 를 사용해서 표현한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var str = "World!" 
var element =  <h1> Hello {str}</h1>
 
var item = {
    name"Cheese",
    price: 5
}
var element = <p>{item.name} : ${item.price} </p>
 
var length = 20
var width = 10
function calculateArea(x,y){
    return x * y
}
 
var element = <div>The Area is: {calculateArea(length,width)}</div>
cs


- Using JSX with Attributes

Attribute 표현시 절대로 curly braces를 quotes("")로 감싸면 안된다. 


1
 var element = <img src ={product.imageURL}></img>
cs


- Style Object

위에서와 같이 동일하게 style object 를 curly braces  안에 넣어주면 된다.

1
2
3
4
5
6
7
var styleObject = {
        backgroundColor: 'red',
        color:'blue',
        fontSize: 25,
        width: 100
}
var element = <input style = {styleObject}/>
cs


object 로 정의 안하고 바로 사용할 경우에 바깥쪽 {} 는 JSX표현이고 안쪽에 {} 는 style object 를 표현한것이다.

1
var element = <input style = {{width:200,height:100}}/>
cs


- Nested Elements

하나로 wrapping  하는 것을 권장한다.

1
2
3
4
5
6
var element = (
        <div>
            <div>Hello World</div>
            <div>Hello World</div>
        </div>
)
cs



Functional Components

- React Components

React Components는 독립적이고 재사용 가능한 React Element를 만들어 낸다. React Components는 Functional ComponentsClass Components로 구성된다.


- Functional Components

Functional Components는 React Elements를 출력한다. 관습적으로 Function의 첫글자는 대문자로 쓴다.

1
2
3
4
5
6
7
8
function HelloWorld(){
    return <h1>Hello World!</h1>
}
 
ReactDOM.render(
    <HelloWorld />,
    document.getElementById("root")
)
cs


- Properties  추가

Functional Components는 React Elements를 출력한다. 관습적으로 Function의 첫글자는 대문자로 쓴다.

1
2
3
4
5
6
7
8
9
function HelloWorld(props){
    return <h1>Message: {props.message}</h1>
}
 
ReactDOM.render(
    <HelloWorld message="Hello World!"/>,
    document.getElementById("root")
)
 
cs


Composition

- Composing Components

Functional Components 는 다른 Functional Components 를 결과 값으로 포함할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function ShoppingTitle(props){
    return (
        <div>
            <h1>{props.title}</h1>
            <h2>Total Number of Items: {props.numItems}</h2>
        </div>
    ) 
}
function ListItem(props){
    return <li>{props.item}</li>
}
function ShoppingList(props){
    return (
        <div>
            <h3>{props.header}</h3>
            <ol>
                <ListItem item = {props.items[0]}/>
                <ListItem item = {props.items[1]}/>
                <ListItem item = {props.items[2]}/>
            </ol>
        </div>
    )
}
function ShoppingApp(props){
    return (
        <div>
            <ShoppingTitle title = "My Shopping List" numItems = "9"/>
            <ShoppingList header = "Food" items = {[ "Apple","Bread","Cheese"]}/>
            <ShoppingList header = "Clothes" items = {[ "Shirt","Pants","Hat"]}/>
            <ShoppingList header = "Supplies" items = {[ "Pen","Paper","Glue"]}/>
        </div>
    )
}
ReactDOM.render(
    <ShoppingApp/>,
    document.getElementById("root")
)
cs


Conditional Rendering

- Conditional Rendering

Functional Components 의 결과값을 프로퍼티에 따라서 결정할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
function Feature(props){
    if (props.active == true){
        return <h1>This feature is active</h1>
    }
    else{
        return <h1>This feature is not active</h1>
    }
 
}
 
function Feature(props){
    return <h1>This feature is {props.active? "active" : "not active"}</h1>
}   
cs


Module 1 내용 정리 끝.


728x90
반응형

+ Recent posts