1. props

props는 생성자 인자로 비유해서 이해했다.

MyComponent 태그를 보면 속성=값 으로 인자를 넘겨줬다.

객체를 찍어낼때 생성자 인자로 "a", "b"를 넘겨줬다고 생각하면된다.

2.state

state는 클래스의 private 멤버로 비유해서 이해했다.

state를 정의하려면 위와 같이 하면 된다.
생성자 써주고 그 안에다 정의해주면 된다. 걍 방식이다.

제품으로 치면 props는 외부 연결선이고 state는 내부 전선에 해당한다.

내부 전선이 밖으로 나와있으면 좋은제품이라할수없다.

위와 같이 구현하면 <App/>을 렌더링하는 입장에서는 state가 있는지 없는지 모른다.

즉 외부에선 모른다.

 

<응용1>

props로 넘어온 애들을 state에 세팅해주고 사용할 때는 위와 같이

constructor만들고 그안에서 this.state=해서 세팅해주면된다.

 

<응용2>

컴포넌트 안에 내부 컴포넌트가 있을때, 자신의 state를 내부 컴포넌트의 props로 계층화해서 내려줄 수 있다.

 

3. 개꿀

class안의 state, props가 변하면 render가 자동으로 재호출되고 하위 컴포넌트의 render도 싹다 호출된다고 한다.
하나가 변경됐을 때, 그에 영향을 받는 하위 애들이 알아서 갱신되니까 편하다.
실제로 각 컴포넌트 render() 함수 가서 console.log찍어보면 알 수 있다.

 

<주의할점>

state가 바뀌면 그 state를 참조하는 모든 자식컴포넌트들이 다시 render되는데,
이때 this.state.a=b 일케 변경시키면 값은 바뀌지만 render가 안된다.
this.setState({ a:b });
일케 해줘야 다시 render가 된다.


내가 처음생각한건 private변수라 setter 메쏘드를 통해서만 접근이되는줄알았는데

그건 아니고 setter 안에 render를 다시하게끔 내부구현이 되어있는듯 싶다.

' > 리액트' 카테고리의 다른 글

[리액트]형상관리  (0) 2019.08.31
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31
[리액트]컴포넌트  (0) 2019.08.31
[리액트]플젝 만들기  (0) 2019.08.31

리액트의 컴포넌트는 걍 나만의 태그를 만드는 것이라 생각하면 쉽다.

<div>, <p> 이런거는 원래 html기본 태그고

<Content> <Controls>처럼 내맘대로 이름지어서 태그를 쓸수있다.

클래스로 만들고 클래스이름.js로 만든다.

 

<Article.js>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component } from "react";
class Article extends Component {
  render() {
    
    return (
      <div>
        <h3>{this.props.article.title}</h3>
 
        <p>{this.props.article.desc}</p>
      </div>
    );
  }
}
 
export default Article;
 
cs
 

Component 클래스를 상속받아서 만들어야하고

render함수에 이 컴포넌트가 어떤내용을 보여줄지 기술한다.

여러개의 태그가 병렬로 있으면 금마들을 아우르는 태그가 꼭 있어야된다. 걍 리액트 문법이다.

위같은경우 <h3>태그랑 <p>태그가 병렬로 있어서 <div>로 감싸줬다.

플젝 만들면 생기는 App.js도 컴포넌트다.

다른 데에서 사용하려면 export를 해주고

쓰고자하는 파일에서 import를 해주면된다.

 

화살표 따라가기

index.js를 따보면 index.html에 있는 div를 id로 끍어와서 거기에 <App>태그를 렌더링하는걸 볼수있다.

App.js를 따보면 App컴포넌트의 render()가 있고 그 안에 <Subject> 태그가 있다.
Subject.js를 따보면 Subject컴포넌트의 render()가 있고 안에 내용이 있다.

 

컴포넌트를 클래스로 태그를 객체로 이해하면 쉽다.

 

' > 리액트' 카테고리의 다른 글

[리액트]형상관리  (0) 2019.08.31
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31
[리액트]props state  (0) 2019.08.31
[리액트]플젝 만들기  (0) 2019.08.31

갓 생활코딩형님의 리액트 입문 수업이 있어서 공부했다.

https://www.opentutorials.org/module/4058

 

React

수업소개 리액트 입문 수업입니다. 이 수업에서는 아래와 같은 내용을 다루고 있습니다.  리액트를 사용하는 이유 리액트의 컴포넌트를 만드는 법 리액트와 불변(immutable)의 관계 아래 내용은 다루고 있지 않습니다.  데이터베이스 서버와 연동 redux 수업대상 리액트를 통해서 재사용 가능한 사용자 정의 태그(컴포넌트)를 만들고 싶은 분, single page application을 구현하고 싶은 분 수업을 보는 다른 방법 Youtube 재생목록 수업에

www.opentutorials.org

리액트도 express처럼 플젝 기본 골격을 제공해주는게 있다.

 

nodejs 깔고 npm으로 create-react-app 설치하고
create-react-app
directory_name 해주면

 

해당 디렉명으로 리액트 프로젝트가 설치된다.
어차피 실제 화면에 뿌려질 내용들은 api서버를 따로만들어 읽어오면 되기 때문에

프론트엔드를 관리하는 서버를 만드는 것이다.
나중에 api서버를 구축해서 두 서버를 같이 켜주면 된다.

 

' > 리액트' 카테고리의 다른 글

[리액트]형상관리  (0) 2019.08.31
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31
[리액트]props state  (0) 2019.08.31
[리액트]컴포넌트  (0) 2019.08.31
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 확장성이 강력한 정렬 프로그램 만들기
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int intCompare(void *a, void *b)
{
    return *((int *)a) > *((int *)b);
}
int doubleCompare(void *a, void *b)
{
    return *((double *)a) > *((double *)b);
}
int floatCompare(void *a, void *b)
{
    return *((float *)a) > *((float *)b);
}
int charCompare(void *a, void *b)
{
    return *((char *)a) > *((char *)b);
}
int shortCompare(void *a, void *b)
{
    return *((short *)a) > *((short *)b);
}
void sort(void *arr, int len, size_t esize, int (*compare)(void *void *));
int main()
{
    int a[5= {31452};
    sort(a, 5sizeof(int), intCompare);
    for (int i = 0; i < 5++i)
        printf("%d ", a[i]);
}
void generic_swap(void *arr, int i, int j, size_t size//넘어올때는 char*로 넘어오지만 받는게 void*니까 또 캐스팅 필요
{
    //memcpy말고 char배열을 swap하듯이 해도된다.int면 char를 4번 스왑한다는 뜻.
    char *aray = (char *)arr;
    char *= aray + i * size*= aray + j * size;
    char tmp;
    for (int i = 0; i < size++i, ++p, ++q)
    {
        tmp = *p;
        *= *q;
        *= tmp;
    }
}
void sort(void *arr, int len, size_t esize, int (*compare)(void *void *))
{
    void *tmp = malloc(esize);
    for (int i = 0; i < len - 1++i)
        for (int j = i + 1; j < len; ++j)
        {
            if (compare((char *)arr + esize * i, (char *)arr + esize * j)) //주소+정수 연산으로 주소를 뽑아내는데
            //i*가리키는 타입의 크기만큼 가게 된다. void*일경우 사이즈를 계산하지 못하기 때문에
            //char*로 형변환 시킨 후 i*데이터타입의 크기를 해주면 그만큼 넘어간 주소가 된다.
            //compare함수에 void*를 두개 넘겨주는 이유는, 함수를 파라미터로 넘겨줄때 인자가 int*이런식으로
            //타입이 정해져버리면 sort함수의 인자를 통일시킬수없기 때문에
            //(void*,void*)형식의 함수로 넘겨주고, compare함수 내에서 자체적으로 해결해야한다.
            {
                //compare함수에서 넘어온 값을 믿고 그냥 바이트단위로 복사한다.
                //여기서도 핵심은 void*를 char*로 변환해서 주소+정수연산을 이용한다는 점이다.
                //memcpy(tmp,(char*)arr + esize*i, esize);
                //memcpy((char*)arr+i*esize, (char*)arr+j*esize, esize);
                //memcpy((char*)arr+j*esize,tmp,esize);
 
                generic_swap(arr, i, j, esize); //넘길때 void* + 정수 하면 안된다고!
            }
        }
    free(tmp);
}
 
cs


<링크>

https://www.acmicpc.net/problem/15685


<소스코드>

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<stdio.h>
#include<vector>
using namespace std;
int pan[101][101];
void check(int x, int y, int d, int g)
{
    vector<int> v;
    v.push_back(d);
    for (int i = 0; i < g; ++i)
    {
        int size = v.size();
        for (int j = size - 1; j >= 0--j)
        {
            int dir = v[j];
            int toDir = (dir + 1) % 4;
            v.push_back(toDir);
        }
    }
    int size = v.size();
    pan[x][y] = 1;
 
    for (int i = 0; i < size++i)
    {
 
        int dir = v[i];
        switch (dir)
        {
        case 0:++x; break;
        case 1:--y; break;
        case 2:--x; break;
        case 3:++y; break;
        }
        pan[x][y] = 1;
    }
}
int main()
{
    int N;
    scanf("%d"&N);
    while (N--)
    {
        int x, y, d, g;
        scanf("%d%d%d%d"&x, &y, &d, &g);
        check(x, y, d, g);
    }
    int ans = 0;
    for (int x = 0; x<100++x)
        for (int y = 0; y <100++y)
        {
            if (pan[x][y] && pan[x + 1][y] && pan[x][y + 1&& pan[x + 1][y + 1])
                ++ans;
        }
    printf("%d", ans);
}
 
cs


<풀이>

그림처럼 이전세대의 선분 하나랑 다음세대의 선분 한쌍이 각각 관계가 있다.


시작점부터의 방향만을 리스트로 나타내면 다음과 같다. 

잘 보면 규칙성을 발견할 수 있다. 

기존 세대의 방향 맨 끝부터 봤을때 기존 방향에서 왼쪽으로 90' 꺾은 방향으로 다음세대의 방향이 결정된다.

①↑에서 ←

←에서

↑에서 ←

→에서

이런 규칙으로 변한다. 근데 문제에서도 친절하게


  • 0: x좌표가 증가하는 방향 (→)
  • 1: y좌표가 감소하는 방향 (↑)
  • 2: x좌표가 감소하는 방향 (←)
  • 3: y좌표가 증가하는 방향 (↓)

라고 되어있기 때문에 다음방향 = (이전방향+1)%4 이 된다.

이런식으로 K세대까지의 방향만을 쫙 만들어놓은 후

시작점부터 해당좌표에 체크해준다.


+ Recent posts