Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Comment thread
imballinst marked this conversation as resolved.
Outdated

**Bug fixes**

Expand Down
64 changes: 39 additions & 25 deletions wiki/react-router.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Comment thread
imballinst marked this conversation as resolved.
Outdated

```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 <WrappedComponent {...this.props} />;
}
// 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 <EuiLink {...props} href={to} onClick={onClick} />;
}
```

```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);

// <App> *must* be a child of <Router> because <App> depends on the context provided by <Router>
ReactDOM.render(
<Router>
<AppMount />,
<App />,
</Router>,
appRoot
)
Expand Down