August 13, 2022 • ☕️☕️ 8 min read
비 미쳤니
input
태그 이모저모<input>
태그에는 onPaste
라는 리스너도 있다. 붙여넣기 하는 텍스트에 대해 선처리를 할 때 사용한다.<input type="file" />
은 capture 특성을 지원한다
URL.createObjectURL()
메서드에 인자로 event.target.files
객체를 넣어주면 미리보기를 할 수 있는, 임시 로컬 이미지 경로를 반환해준다. 특정 파일 객체나 로컬 파일, 또는 데이터의 참조를 가리키는 새로운 객체 URL을 생성하며, 생성한 값은 현재 창이나 객체를 생성한 문서 내에서만 유효하다. 새 객체 URL은 File
객체나 Blob
객체로 표현된다.
Blob(Binary Large Object) 큰 객체를 2진법으로 저장하는 것으로, 자바스크립트에서 이미지, 영상, 멀티미디어 데이터를 사용하는 객체이다.
이렇게 만든 ObjectURL은 URL.revokeObjectURL()
로 취소 할 수 있다. URL.createObjectURL()
로 만들어진 URL은 해당 document 의 라이프타임이 끝나기 전까지는 계속 사용하는 것으로 생각하여 가비지컬렉팅 에서 제외되어 메모리 누수가 발생할 수 있다.
plugin은 eslint rule들이 들어있는 하나의 rule set이다. 일반적으로 eslint-plugin-${plugin-name}
의 형태를 갖는 패키지다. 플러그인을 사용하기 위해서는 필요한 플러그인을 설치하고, eslint 설정 파일의 plugins 프로퍼티에 추가한다.
{
plugins: ["react"];
}
(플러그인을 추가할 때 prefix인 eslint-plugin-
부분은 생략 가능하다.)
플러그인을 적용한다는 것은 플러그인에 정의되어 있는 Rule set을 사용하겠다는 것을 의미하지는 않는다. 플러그인은 여러가지 Rule set을 제공할 뿐, 특정 룰을 사용하려면 이를 직접 작성해야 한다. 사용하고자 하는 룰은 rules 프로퍼티를 통해 정의한다.
플러그인이 제공하는 Rule set의 수는 상당히 방대하고 이것들을 모두 수동으로 설정하는 것은 번거로운 일이다. 그래서 등장한 것이 sharable config
다. sharable config
는 일반적으로 eslint-config-${config-name}
형식의 이름을 갖는 패키지다. 사용하려는 rule set을 수동으로 적용하는 것이 아닌 sharable config를 적용하는 것을 통해 방대한 rule set을 한번에 적용할 수 있다.
sharable config의 사용여부는 ESLint 설정파일의 extends 프로퍼티에 해당 sharable config를 추가하면 된다.
{
"extends": ["prettier"]
}
일부 플러그인은 sharable config를 함께 가지고 있다. plugin과 config를 각각 설치하는 것이 아닌 plugin 설치를 통해 config 까지 함께 설치되는 것이다. plugin이 내장하고 있는 config를 사용하기 위해서는 sharable config 설정과 동일한 방법으로 하돼 plugin:
prefix를 붙여준다.
{
"extends": ["plugin:react/recommended"]
}
eslint-plugin-react
가 제공하는 recommended config를 사용하는 예제로 prefix인 eslint-plugin은 생략 가능하다.
plugin이 제공하는 config를 확인하기 위해서는 해당 플러그인의 root/index.js 를 참고하면 된다. (일반적으로) index.js 에서 export 하는 Object에서 configs property를 통해 어떤 config가 제공되고 있는지 확인 할 수 있다.
Ref https://code-logs.github.io/eslint---plugin-and-extends
mobx의 reaction
이라는 메서드로 부수효과를 실행할 수 있다. observable state에 대한 consumer를 만들어내거나, 무언가 관련된 요소가 바뀔 때 자동적으로 부수효과를 실행할 수 있다.
mobx 최신 버전에서는 autorun
이라는 메서드를 사용한다.
import { autorun } from "mobx";
autorun(effect: (reaction) => void)
autorun
과 유사하지만, 관찰할 observable을 좀 더 세밀하게 위해서 reaction
을 사용한다.
reaction(() => value, (value, previousValue, reaction) => { sideEffect }, options?).
첫 번째 data 함수는 트래킹되어 두 번째 effect 함수에 대한 input으로 사용되는 데이터를 반환한다. 부수효과는 오직 data 함수에서 액세스 된 데이터에만 반응한다.
아래 예제를 살펴보자. myStore
라는 관찰 가능한 상태(observable state)가 있고, myStore.tab
이 변경되었을 때 자동으로 console.log("tab changes")
를 실행한다.
import { reaction } from "mobx";
reaction(
() => this.myStore.tab,
() => console.log("tab changes");
);
Ref https://ko.mobx.js.org/reactions.html
String.match(regex)
문자열이 정규식과 매치되는 부분을 검색하여, 일치하는 문자열이 있다면 해당 문자열들을 담은 배열을 반환한다.
const str = "For more information, see Chapter 3.4.5.1";
const re = /see (chapter \d+(\.\d)*)/i;
const found = str.match(re);
console.log(found);
// [ 'see Chapter 3.4.5.1',
// 'Chapter 3.4.5.1',
// '.1',
// index: 22,
// input: 'For more information, see Chapter 3.4.5.1' ]
index
는 제로 베이스의 인덱스를 나타내며, input
은 처음에 주어졌던 원본 문자열을 나타낸다. 반환되는 배열이 특이해서 기록해둠. ‘제로 베이스의 인덱스’라는 것은, 원본 문자열에서 첫 번째로 매칭된 문자열의 시작 인덱스라는 것 같다.
Ref https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/match
<mark>
태그참조
나 인용
처럼 둘러싼 맥락과 연관이 강한 텍스트를 강조하기 위해 사용하는 목적이다.aria-label
이나 aria-labelledby
와 같은 어트리뷰트를 사용하는 것도 금지한다.ARIA: mark role HTML
<mark>
태그와 같은 목적으로 사용한다. 일반적으로role="mark"
대신<mark>
태그를 사용하는 것을 권장한다.
Ref https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/mark_role
aria-live=POLITENESS_SETTING
는 스크린 리더가 live regions에 대한 업데이트를 처리할때 우선 순위를 설정하는 데 사용되며, 가능한 세팅으로 off
, polite
, assertive
가 있다. 기본 설정은 off
입니다. 이 속성은 단연코 가장 중요하다.(?)
뭔가 active한 상태가 바뀌었을 때 스크린리더가 바로 해당 요소를 읽어줄 것인지, 무시할 것인지 결정하는 것 같다.
뭐 어쩌라는 건지! 🤷♀️
Ref https://developer.mozilla.org/ko/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
object는 선언당시의 순서가 보장되지 않는다. object의 key를 숫자형태로 하면 변수를 선언할 당시의 필드 순서와 다르게 정렬될 수 있다. Object.entries()
Object.keys()
, Object.values()
등의 메서드로 배열화하면 생각과 다른 순서가 될 수 있으니 sort 로직을 추가하는 것이 안전하다.
next.js 사용 시, next.config.js 에 i18n 설정을 추가해서 간단하게 locale을 적용할 수 있다. (Ref)
<ul>
태그는 list
role을, <li>
태그는 listitem
role을 기본적으로 갖고 있다. RTL에서 screen.getAllByRole('listitem')
로 li 엘리먼트들을 가져올 수 있다.
RTL에서 within
API를 쓰면 찾은 element 안에서 RTL Query를 사용할 수 있다.
import { screen, within } from "@testing-library/react";
const topScoreBarElements = screen.getAllByTestId("rating-bar-item");
expect(within(topScoreBarElements[4]).getByText("10만")).toBeInTheDocument();
오래된 윈도우 컴퓨터에서 개행 문자 \n
이 동작하지 않을 수도 있을 때, \r
(carriage return)을 사용한다.
css [attr^=val]
- attr
속성이 val
문자열로 시작하는 요소들을 가리킨다.
css로 counter-increment를 설정할 수도 있다. 짱 좋다! (Ref)
‘Pn 룰’을 적용해서, P1~P5까지 리뷰어가 코멘트를 강조하고 싶은 정도를 표현한다. ‘nit’같은 용어도 종종 사용하지만, 중요도를 5단계로 나누어 프로그램의 동작에 영향을 미치는 리뷰인지, 그냥 개인적인 의견인지를 구분할 수 있어서 커뮤니케이션 비용을 낮출 수 있다.
팀에서 새롭게 적용 중인데, 리뷰를 남기는 입장에서도, 받는 입장에서도 간편하게 사용하고 있다. 😊
Ref https://blog.banksalad.com/tech/banksalad-code-review-culture/
<img>
의 alt
alt 텍스트는 가능한 이미지를 설명할 수 있어야 한다. 하지만 너무 길어서는 안 되고 (100자 이상), 의미 없는 이미지(그저 장식용?)에는 alt 텍스트가 불필요하다.
또한 단순히 이미지를 묘사하는 alt 텍스트가 아니라, 제공하는 컨텐츠의 맥락에 맞는 섬세한 설명이 필요하다.
권장하진 않지만, 어쩔 수 없이 텍스트를 표시하는 이미지를 사용할 경우에는 alt 텍스트에 해당 이미지에 표시된 텍스트를 넣는다.
링크같은 상호작용 기능을 하는 이미지 요소에는, 해당 이미지가 어떤 동작을 수행할 수 있는지 알려주는 alt 텍스트가 필요하다.
☔️ 비가 진짜로 미친 것 같다~ 26년 생애 처음 보는 상황이었는데, 정말 온 동네가 물에 잠겨서 첨벙첨벙 집에 오면서 연신 ‘와~ 와~’ 소리가 났다. 천둥번개도 쳤는데, 번개가 처음 칠 때 신이 강림한 줄 알았다. 2초 뒤에 들린 천둥은 총소리를 연상케 했다. 엄마가 오바 떨지 말라고 했는데, 80년 만의 기록적인 폭우였다고 한다. 그리고 내가 살고 있는 동작구에 가장 비가 많이 내렸다고 한다. ^^ 우리동네의 많은 역들은 침수되어 무정차통과했고, 새벽까지 재난문자가 계속 왔다… 너무 무서웠당.
그렇게 수요일 약속을 모두 취소했는데, 수요일 아침이 되자마자 해가 쨍☀️ 떴다 ^^ 억울하다. 인류는 이렇게 벌받는구나. 사흘 연휴가 주어졌는데, 다시 미친듯이 비가 온다… 니 맘대로 하거라…