-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 잡다한 설정 수정 * 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
1 parent
c530407
commit 593de56
Showing
72 changed files
with
8,722 additions
and
1,254 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Binary file not shown.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` 라우팅 컴포넌트를 만들 수 있습니다. |
Oops, something went wrong.
593de56
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
blog – ./
blog-git-main-jonghopark95.vercel.app
blog-jonghopark95.vercel.app
pumpkiinbell.com
www.pumpkiinbell.com