이벤트 핸들러에 추가적인 매개변수를 전달하는것이 일반적임

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

 

버튼에 이벤트 핸들러 넣는 방법은 아래와 같음 

  1. 버튼을 만든다 (<button>
  2. 버튼을 클릭했을때 함수를 만든다 (handleClick)
  3. 버튼에 클릭할때 함수를 설정한다 (onClick)
  4. 바인딩 한다 (this.handleClick.bind(this))
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

 

 {this.state.isToggleOn ? 'ON' : 'OFF'}

 

저희 부부는 2019년 8월경에 신혼집으로 이사를 했고,
현재 신랑이 세대주, 제가 세대원인 형태입니다

저는 2019년 1월~7월 제가 단독으로 살면서 전세자금대출 원금과 이자를 갚았기 때문에 주택소득공제를 받으려했죠.
신혼집은 신랑이름으로 하고, 신랑이 대출을 받았기 때문에 2019년 8월~12월에 대한 부분은 신랑이 주택소득공제를 받으려했습니다.

그런데,,,,,, !!!
그렇게 되지가 않더라고요.

2020년 1월, 2019년에 대한 연말정산 주택소득공제를 받고싶으면
2019년 12월 31일에 제가 세대주였어여 하더라고요.
아니면 지금은 세대원이지만, 현재 세대주인 신랑이 주택소득공제를 받지 않아야 해요.

즉, 2019년에 대해서 신랑 혹은 저 둘 중 하나만 주택소득공제를 받을 수가 있더라고요. T.T 

아니면 둘 다 세대주 이면 가능한데요
1가구에 2세대주는 어렵습니다.
아파트의 경우 안된다고 보시면 되는데,
그게 부모-자식 관계일 경우는 세대주를 분리할 수 있다고 하네요.
같은 주소를 가진 아파트에서 저희 같은 부부가 각각 세대주를 하는거는 방법이 없는 거 같아요.

흑, 그래서 저는 제 주택소득공제를 포기했고....

또르르...
괜히 손해 본 거 같아요.

제가 결혼전에 제 전세자금대출 열심히 갚았던 거는 왜 날라가는 건지
저는 이해가 되지 않는데요,
법이 그러하니 어쩌겠습니까...

결혼하시는 분들 참고하세욤. ^.^

엘라스틱서치에서 샤드는 refresh, flush, optimize API 과정을 통해 관리된다.
엘라스틱서치의 위의 내용은 모두 루씬 내용인데 서로 용어가 다르기 때문에 잘 정리해 둘 필요가 있다.

루씬 엘라스틱서치
flush refresh
commit flush
merge optimize API

루씬에서는 데이터가 in-memory buffer 기반으로 처리된다.
데이터변경사항이 들어오면 segment를 생성하고, 시스템 캐시에 캐시된 후에, 디스크 동기화가 이루어짐.

1. 루씬에서의 flush = 엘라스틱서치의 refresh.
- segment 생성시 커널 시스템 캐시에 세그먼트가 캐시되어 읽기가 가능해진다.
- 루씬의 ReOpen() 함수를 이용해 IndexSearcher에서 읽을 수 있는 상태.
- 일정주기마다 업데이트 된 문서가 ReOpen() 함수로 처리.

- es 클러스터에 존재하는 모든 샤드에서는 기본적으로 1초마다 한번씩 refresh작업이 수행된다.
- 인덱스를 새로고침한다는 의미인데, refresh가되면 새로 추가한 데이터의 검색이 가능해진다.
- 대량 인덱스 시에는 -1로 비활성화해두면 인덱싱할때 이점이 있다.

2. 루씬에서의 commit = 엘라스틱서치의 flush.
- 물리적으로 디스크 기록을 수행하는 fsync() 함수 호출 작업이다.
- flush가 있기 때문에 매번 commit 필요가 없고, 일정 주기로 commit이 수행된다.
- 루씬에서의 flush작업은 디스크로 쓰기가 이루어지기 전이기 때문에, flush작업까지만 되고 시스템에 문제가 발생하면 데이터 유실 발생 가능성이 있다.

- es에서의 flush는 루씬의 commit 작업과 함께 새로운 translog를 시작한다.
- * translog는 루씬에는 없는 내용으로 샤드의 장애복구를 위해 재공 되는 특수한 파일이다.
- * 샤드는 자신에게 일어나는 모든 변경사항을 translog에 먼저 기록하고, 내부 루씬을 호출한다.
- * 시간이 지나면 translog 파일 크기도 증가한다. 루씬에서 commit이 이루어지면 translog에서 commit 지점까지의 내용이 삭제된다.
- * 데이터가 커널 시스템 캐시에 있다 디스크에 동기화 되지 못하고 유실될 가능성을 대비하여 transhlog를 만든 것이다.
- es에서 flush 작업은 default로 5초에 한번씩 수행되고, api를 통해 flush 주기 조절이 가능하나 추천하지 않는다.

3. 루씬의 merge = 엘라스틱서치의 optimize API
- 검색 성능을 높이기 위해 검색 대상이 되는 세그먼트를 병합하여 세그먼트 수를 줄이는 작업이다.

- 검색 대상이 되는 세그먼트 수를 줄이면, 검색 횟수를 줄일 수 있고, 검색 성능이 올라간다.
- commit작업을 동반하기 때문에 비용이 크다. 

- es에서는 forced merge API를 통해 루씬 merge 작업을 강제 수행할 수 있다.
- 파편화된 다수 세그먼트들을 병합한다.
- 강제 수행하지 않더라도, 백그라운드로 주기적으로 수행된다.

elasticsearch에서는 nested type을 사용할 수 있다.
문서안에 object array를 저장할 수 있고, 그것이 nested type이다.

es가이드에 나온 예제 처럼 user object를 array형태로 넣을 수 있다.

{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith",
      "score" : 90
    },
    {
      "first" : "Alice",
      "last" :  "White",
      "scroe" : 100
    }
  ]
}


내가 임의로 score라는 필드도 추가해 넣어보았다.
그러면 nested 영역에 들어가지 않는 "group"이라는 필드를 key로 score의 sum을 구하고 싶다면 어떻게 해야할까?

아래와 같이 reverse_nested 구문을 사용하면 된다.
주의 할 것은 먼저 nested한 영역부터 작성해주고 그 안에 reverse_nested, nested 밖 내용을 작성해주면 된다.

  "aggs": {
    "user": {
      "nested": {
        "path": "user"
      },
      "aggs": {
        "score": {
          "sum": {
            "field": "combined_struct.score"
          },
          "aggs": {
            "group_by_key": {
              "reverse_nested": {}, 
              "aggs": {
                "group_sum_score": {
                  "terms": {
                    "field": "group"
                  }
                }
              }
            }
          }
        }
      }
    }
  }

 

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

 

Nested datatype | Elasticsearch Reference [7.5] | Elastic

Because nested documents are indexed as separate documents, they can only be accessed within the scope of the nested query, the nested/reverse_nested aggregations, or nested inner hits. For instance, if a string field within a nested document has index_opt

www.elastic.co

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html

 

Nested Aggregation | Elasticsearch Reference [7.5] | Elastic

A special single bucket aggregation that enables aggregating nested documents. For example, lets say we have an index of products, and each product holds the list of resellers - each having its own price for the product. The mapping could look like: PUT /p

www.elastic.co

 

elasticsearch에는 fielddata와 doc_values라는 것이 있고, 주요 개념이므로 이해가 필요하다.
더 근본적으로는 루씬의 개념이기 때문에 루씬에서 storedField와 docValue내용을 찾아보는 것이 좋다.

elasticsearch에서 data를 mapping할때에 keyword type과 text type이 있다.
keyword type의 경우 exact매칭에서 사용하고, text type의 경우 analyzed 매칭에 사용된다.
text type의 경우는 형태소 분석을 통해 field를 여러 terms로 나눠서 역인덱싱 과정을 거치게 되고,
keyword type은 그대로 역인덱싱 된다.
* 역인덱스란 키워드가가 어떤 문서에 포함되는지를 저장한다.

검색(search)이라는 것은 "어떤 문서가 이 키워드를 포함하는지가 궁금"하므로 역인덱스된 정보를 통해 검색이 빠른 검색이 가능하다.
그러나 sort, aggregation, accessing field value 와 같은 패턴은 "이 문서에서 이 field value값이 무엇인지"가 관심이므로 역인덱스 정보가 아닌 document를 key로, field정보를 담은 데이터 구조가 필요하다. 그 데이터 구조가 fielddata라는 것이다.

key value
doc1 a:1, b:4, c:7
doc2 a:2, b:5, c:8
doc3 a:3, b:6, c:9

 

그런데 fielddata의 경우 in-memory구조로 작동하기 때문에 많은 heap memory를 소비하게된다. 일단 field가 heap에 로딩되면 그것은 segment의 lifetime동안 남아있게된다. 따라서 비용이 높은 프로세스가된다.

text field를 사용하게 되면 fielddata 데이터 구조를 사용할 수 있는데 위의 설명과 같이 높은 비용때문에 default false로 되어있다.
필요한 경우는 fielddata=true로 옵션을 변경하여 사용하되, memory사용에 주의한다.

keyword field에서는 fileddata의 in-memory에서 동작하는 구조를 개선하여, on-disk data structure인 doc_values 사용이 가능하다.
doc_values는 아래와 같이 column-oriented fashion으로 더욱 유리하게 sort, aggregation 등을 할 수 있다.

key doc1 doc2 doc3
a 1 2 3
b 4 5 6
c 7 8 9


keyword type과 text type은 이렇게 analyzed 되냐 안되냐의 차이뿐 아니라 fielddata, doc_values와 같은 데이터 구조 사용 여부도 달라지므로 적절한 data mapping과 옵션 설정이 중요하다.

 

 

* 위의 설명은 친절한 es 가이드와 루씬내용을 따로 찾아 정리하였습니다.
* es 가이드를 상세히 읽고, 그에 따른 루씬 내용을 찾아보면 이해하기가 좋은 것 같아요.

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html

 

fielddata | Elasticsearch Reference [7.5] | Elastic

Most fields are indexed by default, which makes them searchable. Sorting, aggregations, and accessing field values in scripts, however, requires a different access pattern from search. Search needs to answer the question "Which documents contain this term?

www.elastic.co

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/doc-values.html

 

doc_values | Elasticsearch Reference [7.5] | Elastic

Most fields are indexed by default, which makes them searchable. The inverted index allows queries to look up the search term in unique sorted list of terms, and from that immediately have access to the list of documents that contain the term. Sorting, agg

www.elastic.co

 

UI개발할때 항상 내부의 기능과 연결이 되어있으면 코드의 유지보수가 어려운데 storybook을 사용하면 isolation이 되서 UI만 따로 구성할 수 있는 장점이 있다. UI컴포넌트들을 생성하고, 그 컴포넌트들을 사용하면 끝! 

동작하는 방식은 yarn으로 설치를 하고 나만의 stroybook을 로컬에 띄우고 UI를 컴포넌트 별로 생성하고 관리하면 된다. 스토리북을 처음에 동작시키면 아래와 같이 브라우저에 표시가 되는데

ㅋㅋ

내가 만약 UI 컴포넌트 별로 여러개의 UI를 만든다면 아래와 같이 구성이 된다. story에는 내가 작성한 코드들이 들어있고, 버튼을 누를때 action이 있다면 actions에 표시가 된다. 

https://storybook.js.org/docs/basics/introduction/

 

https://storybook.js.org/docs/basics/introduction/

Introduction Edit this page Storybook is a user interface development environment and playground for UI components. The tool enables developers to create components independently and showcase components interactively in an isolated development environment.

storybook.js.org

스토리북에 대해서 학습하고 싶으면 아래 튜토리얼을 따라해보자.

https://www.learnstorybook.com/

 

Storybook Tutorials

Learn Storybook teaches frontend developers how to create UIs with components and design systems. Our free in-depth guides are created by Storybook maintainers and peer-reviewed by the open source community.

www.learnstorybook.com

Airbnb에서도 다음과 같이 자신만의 stroybook을 만들어서 운영하고 있다. 

https://airbnb.io/react-dates/?path=/story/drp-calendar-props--open-up

 

Storybook

 

airbnb.io

이렇게 UI 컴포넌트 별로 생성해서 프로젝트에서의 의존성을 줄이는게 좋을것 같다는 생각!

+ Recent posts