From 805776039e6e45c13716605fa7984836d02e3cd7 Mon Sep 17 00:00:00 2001 From: Try Ajitiono Date: Fri, 4 Oct 2019 20:30:22 +1000 Subject: [PATCH 1/3] Update docs for easier integration with react-router with React Hooks Signed-off-by: Try Ajitiono --- wiki/react-router.md | 64 +++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/wiki/react-router.md b/wiki/react-router.md index bee5c2fe8ee..bd19ccef1cf 100644 --- a/wiki/react-router.md +++ b/wiki/react-router.md @@ -248,45 +248,59 @@ export const getRouterLinkProps = to => { ## react-router 5.x -The React Context handling has changed in in 5.0 and we can't rely on it anymore. A solution is to create -an `extractRouter` HOC that will intercept the router and send it to your custom handler. +In react-router 5, we can fully capitalize in the React Hooks utility, in this case, `useHistory`. Using this, we do not need other HOC wrapper files and global router variable. We just need to create the file below, and then use it anywhere by importing `EuiCustomLink`. There is an example repository for this: https://github.com/Imballinst/elastic-react-router-hooks. +```jsx +// File name: "EuiCustomLink.js". +import React from 'react'; +import { EuiLink } from '@elastic/eui'; +import { useHistory } from 'react-router'; -```js -// extractRouter.hoc.js -import { withRouter } from 'react-router-dom'; - -export const extractRouter = onRouter => WrappedComponent => - withRouter( - class extends Component { - componentDidMount() { - const { match, location, history } = this.props; - const router = { route: { match, location }, history }; - onRouter(router); - } - - render() { - return ; - } +// Most of the content of this files are from https://github.com/elastic/eui/pull/1976. +const isModifiedEvent = (event) => + !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); + +const isLeftClickEvent = (event) => event.button === 0; + +export default function EuiCustomLink({ to, ...props }) { + // This is the key! + const history = useHistory(); + + function onClick(event) { + if (event.defaultPrevented) { + return; } - ); + + // If target prop is set (e.g. to "_blank"), let browser handle link. + if (event.target.getAttribute('target')) { + return; + } + + if (isModifiedEvent(event) || !isLeftClickEvent(event)) { + return; + } + + // Prevent regular link behavior, which causes a browser refresh. + event.preventDefault(); + + // Push the route to the history. + history.push(to); + } + + return ; +} ``` ```jsx -import { extractRouter } from './hoc'; -import { registerRouter } from './routing'; - // App is your app's root component. class App extends Component { ... } -const AppMount = extractRouter(registerRouter)(App); - // *must* be a child of because depends on the context provided by ReactDOM.render( - , + , , appRoot ) From d6cfc85891f8bfd348ca09c4d50fa3a38db99ab3 Mon Sep 17 00:00:00 2001 From: Try Ajitiono Date: Sat, 5 Oct 2019 12:29:16 +1000 Subject: [PATCH 2/3] add CHANGELOG.md Signed-off-by: Try Ajitiono --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0346eaf0d89..db5afc1c27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added new `EuiColorStops` component ([#2360](https://github.com/elastic/eui/pull/2360)) - Added `currency` glyph to 'EuiIcon' ([#2398](https://github.com/elastic/eui/pull/2398)) - Migrate `EuiBreadcrumbs`, `EuiHeader` etc, and `EuiLink` to TypeScript ([#2391](https://github.com/elastic/eui/pull/2391)) +- Update docs for easier integration with react-router using React Hooks ([#2401](https://github.com/elastic/eui/pull/2401)) **Bug fixes** From ac1845cde10225f4eaa127e0d29e240cd13677de Mon Sep 17 00:00:00 2001 From: Try Ajitiono Date: Wed, 9 Oct 2019 07:49:55 +1100 Subject: [PATCH 3/3] remove changelog entry, re-add react-router handling for 5.0 Signed-off-by: Try Ajitiono --- CHANGELOG.md | 1 - wiki/react-router.md | 50 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db5afc1c27e..0346eaf0d89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ - Added new `EuiColorStops` component ([#2360](https://github.com/elastic/eui/pull/2360)) - Added `currency` glyph to 'EuiIcon' ([#2398](https://github.com/elastic/eui/pull/2398)) - Migrate `EuiBreadcrumbs`, `EuiHeader` etc, and `EuiLink` to TypeScript ([#2391](https://github.com/elastic/eui/pull/2391)) -- Update docs for easier integration with react-router using React Hooks ([#2401](https://github.com/elastic/eui/pull/2401)) **Bug fixes** diff --git a/wiki/react-router.md b/wiki/react-router.md index bd19ccef1cf..f441f708e7e 100644 --- a/wiki/react-router.md +++ b/wiki/react-router.md @@ -248,7 +248,55 @@ export const getRouterLinkProps = to => { ## react-router 5.x -In react-router 5, we can fully capitalize in the React Hooks utility, in this case, `useHistory`. Using this, we do not need other HOC wrapper files and global router variable. We just need to create the file below, and then use it anywhere by importing `EuiCustomLink`. There is an example repository for this: https://github.com/Imballinst/elastic-react-router-hooks. +### react-router 5.0 + +The React Context handling has changed in in 5.0 and we can't rely on it anymore. A solution is to create +an `extractRouter` HOC that will intercept the router and send it to your custom handler. + + +```js +// extractRouter.hoc.js +import { withRouter } from 'react-router-dom'; + +export const extractRouter = onRouter => WrappedComponent => + withRouter( + class extends Component { + componentDidMount() { + const { match, location, history } = this.props; + const router = { route: { match, location }, history }; + onRouter(router); + } + + render() { + return ; + } + } + ); +``` + +```jsx +import { extractRouter } from './hoc'; +import { registerRouter } from './routing'; + +// App is your app's root component. +class App extends Component { + ... +} + +const AppMount = extractRouter(registerRouter)(App); + +// *must* be a child of because depends on the context provided by +ReactDOM.render( + + , + , + appRoot +) +``` + +### react-router 5.1 + +In react-router 5.1, we can fully capitalize in the React Hooks utility, in this case, `useHistory`. Using this, we do not need other HOC wrapper files and global router variable. We just need to create the file below, and then use it anywhere by importing `EuiCustomLink`. There is an example repository for this: https://github.com/Imballinst/elastic-react-router-hooks. ```jsx // File name: "EuiCustomLink.js".