Posted at

SPA で右クリックや shift + クリックなどによる別窓表示に対応させる


経緯

import React, { useCallback, useMemo } from 'react'

import useReactRouter from 'use-react-router'
import { myAction } from './myAction'

export const Link = ({ href, children }) => {
const { history } = useReactRouter()

const onClick = useCallback(e => {
myAction(href)
history.push(href)
e.preventDefault()
return false
}, [href])

const _href = useMemo(() => `#${href}`, [href])

return (
<a href={_href} onClick={onClick}>
{children}
</a>
)
}

上記のようなソースコードを書くと Mac の Meta + click や windows の ctrl + click を押した際に

別のタブで表示されるのではなく現在のタブで history.push(href) が実行される。


各種ライブラリがどのように対応しているか

ライブラリによってチェックしている項目が多少異なるようです。

良い感じに組み合わせてキミの最強の onClick を作ろう!!!!!


gatsbyjs の対応

gatsby/packages/gatsby-link/src/index.js#L137


チェック項目 (一部


  • e.button !== 0

  • e.defaultPrevented

  • e.metaKey

  • e.altKey

  • e.ctrlKey

  • e.shiftKey


next.js の対応

next.js/packages/next/client/link.js#L60


チェック項目 (一部


  • nodeName === 'A'

  • e.nativeEvent.which === 2

  • !isLocal(href)


react router の対応

react-router/packages/react-router-dom/modules/Link.js#L15


チェック項目 (一部


  • (!this.props.target || this.props.target === "_self")

  • !isModifiedEvent(event)