Skip to content

Commit

Permalink
v0.1.0 (#7)
Browse files Browse the repository at this point in the history
* 잡다한 설정 수정

* plugin-client-redirects 추가

* docs 추가

* config 경로 수정

* redirect 문제 수정

* 사이드바 설정

* 댓글 기능을 위한 utterances 관련 로직 추가

* onBrokenLinks 값 수정

* url, organizationname, github 이름 수정

* 문서들 약간의 수정

* logo, favicon 수정

* blog 추가

* rss 를 위한 blog author 추가

* readme 수정

* useLinkClickHandler 추가

* footer 추가

* feedoptions type 수정

* 로고, 잡다한 파일 수정

* darkmode 대응

* Blog 에 댓글 기능 추가

* DocPage utterances 사용 부분 리팩토링

* useUtterance 가 Color mode 를 지원할 수 있도록 수정

* utterance 속성 수정

* docs 가벼운 수정
  • Loading branch information
pumpkiinbell authored Jul 10, 2022
1 parent c530407 commit 593de56
Show file tree
Hide file tree
Showing 72 changed files with 8,722 additions and 1,254 deletions.
42 changes: 2 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,3 @@
# Website
# Blog

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ yarn
```

### Local Development

```
$ yarn start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ yarn build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Using SSH:

```
$ USE_SSH=true yarn deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> yarn deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
Powered by [Docusaurus 2](https://docusaurus.io/), Hosted by [Vercel](https://vercel.com/)
12 changes: 0 additions & 12 deletions blog/2019-05-28-first-blog-post.md

This file was deleted.

44 changes: 0 additions & 44 deletions blog/2019-05-29-long-blog-post.md

This file was deleted.

20 changes: 0 additions & 20 deletions blog/2021-08-01-mdx-blog-post.mdx

This file was deleted.

Binary file not shown.
25 changes: 0 additions & 25 deletions blog/2021-08-26-welcome/index.md

This file was deleted.

22 changes: 5 additions & 17 deletions blog/authors.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
endi:
name: Endilie Yacop Sucipto
title: Maintainer of Docusaurus
url: https://github.com/endiliey
image_url: https://github.com/endiliey.png

yangshun:
name: Yangshun Tay
title: Front End Engineer @ Facebook
url: https://github.com/yangshun
image_url: https://github.com/yangshun.png

slorber:
name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
pumpkiinbell:
name: Jongho Park
url: https://github.com/pumpkiinbell
image_url: https://avatars.githubusercontent.com/u/19240202?v=4
email: [email protected]
161 changes: 161 additions & 0 deletions blog/react-router/useLinkClickHandler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
date: 2022-07-09T21:42
authors: pumpkiinbell
---

# useLinkClickHandler

react-router 를 쓰다보면 종종 특정 컴포넌트를 클릭할 때 location 을 바꾸기 위해 `useNavigate` 를 활용합니다.

<!--truncate-->

예를 들면, 다음과 같은 코드입니다.

```js
function Component() {
const navigate = useNavigate();
// ...

return (
<Button
onClick={(e) => {
e.preventDefault();

navigate.to('~~~');
}}
/>
);
}
```

위 코드는 우리가 원하는 요구사항을 대부분 충족시켜줍니다.

그러나, 이런 구현들을 직접하게 될 경우 예상치 못한 edge case 들이 발생하게 됩니다.

예를 들어 마우스의 휠 중간 버튼을 클릭 했을 때 새 탭이 열리거나, `command, ctrl` 등의 키와 함께 클릭 시 새 탭이 열려야 되는데 그렇지 못하는 문제들이 발생합니다.

react-router 는 이에 대응할 수 있는 `useLinkClickHandler` 라는 훅을 제공해줍니다.

## Usage

[useLinkClickHandler](https://reactrouter.com/docs/en/v6/hooks/use-link-click-handler) 는 react-router-dom 이 제공하는 `<Link>` 컴포넌트가 아닌, 커스텀한 navigator 를 구현할 때 click event handler 로 사용할 수 있는 함수를 반환해줍니다.

다음과 같이 사용합니다.

```js
import { useHref, useLinkClickHandler } from 'react-router-dom';

const StyledLink = styled('a', { color: 'fuchsia' });

const Link = React.forwardRef(({ onClick, replace = false, state, target, to, ...rest }, ref) => {
let href = useHref(to);
let handleClick = useLinkClickHandler(to, {
replace,
state,
target,
});

return (
<StyledLink
{...rest}
href={href}
onClick={(event) => {
onClick?.(event);
if (!event.defaultPrevented) {
handleClick(event);
}
}}
ref={ref}
target={target}
/>
);
});
```
참고로, `useHref` 는 접근성을 위해 basename 을 포함한 full path 를 반환해주는 훅입니다.
## Implementation
useLinkClickHandler 는 [다음과 같이 구현](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/index.tsx#L383-L423)되어 있습니다.
```js
/**
* Handles the click behavior for router `<Link>` components. This is useful if
* you need to create custom `<Link>` components with the same click behavior we
* use in our exported `<Link>`.
*/
export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
to: To,
{
target,
replace: replaceProp,
state,
}: {
target?: React.HTMLAttributeAnchorTarget;
replace?: boolean;
state?: any;
} = {}
): (event: React.MouseEvent<E, MouseEvent>) => void {
let navigate = useNavigate();
let location = useLocation();
let path = useResolvedPath(to);

return React.useCallback(
(event: React.MouseEvent<E, MouseEvent>) => {
if (
event.button === 0 && // Ignore everything but left clicks
(!target || target === "_self") && // Let browser handle "target=_blank" etc.
!isModifiedEvent(event) // Ignore clicks with modifier keys
) {
event.preventDefault();

// If the URL hasn't changed, a regular <a> will do a replace instead of
// a push, so do the same here.
let replace =
!!replaceProp || createPath(location) === createPath(path);

navigate(to, { replace, state });
}
},
[location, navigate, path, replaceProp, state, target, to]
);
}
```
몇 가지 주목해야 할 점이 있습니다.
[**_MouseEvent.button_**](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button#value)
`event.button` 은 마우스가 눌렸을 때 이벤트를 trigger 한 버튼이 어떤 것인지 눌렸는 지 확인할 수 있는 값입니다.
`event.button` 이 0 인 경우는 메인 버튼, 즉 마우스 왼쪽 버튼이 클릭되었음을 의미합니다.
`useLinkClickHandler` 는 클릭된 버튼이 마우스 왼쪽 버튼이 아니라면 별다른 동작을 하지 않습니다.
[**_target_**](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target)
anchor element 는 linked URL 을 보여줘야 할 때 **탭인지, 윈도우인지 (browsing context)** 보여주기 위한 속성값인 `target` 을 받을 수 있습니다.
target 으론 `_self, _blank, _parent, _top` 등의 속성이 있습니다.
`useLinkClickHandler` 는 target 이 `_self` 이거나, 받은 target 이 없는 경우 동작을 수행합니다.
[**_isModifiedEvent_**](https://github.com/remix-run/react-router/blob/381e90515289756e40f1620a4196dbd3cad300e9/packages/react-router-dom/index.tsx#L247-L249)
isModifiedEvent 는 클릭 시 `ctrl, command` 등의 키와 함께 눌렸는지 확인하는 함수입니다.
```js
function isModifiedEvent(event: React.MouseEvent) {
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
}
```
`useLinkClickHandler``modifier` 키들과 함께 클릭이 된 경우 동작을 수행하지 않습니다.
**_replace_**
주석에도 설명되어 있다시피 만약, URL 이 변경되지 않았는데 linkClickHandler 가 호출이 되는 경우 push 대신 replace 로 동작을 수행하게 됩니다.
## 정리
컴포넌트를 `a tag` 로 만들고 `useLinkClickHandler` 를 활용한 컴포넌트를 만들면 접근성을 준수한 `SPA` 라우팅 컴포넌트를 만들 수 있습니다.
Loading

1 comment on commit 593de56

@vercel
Copy link

@vercel vercel bot commented on 593de56 Jul 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.