Dynamic back button in your React app
Tags: react, beginners, javascript
Published: 2020-10-02 22:26:03

Today I was working on my url-shortener React and Node app. I am at the stage where I am building the admin panel, where I can approve Users, see who has signed up, etc. Each of these pages is a component and it has a back button. Since I found myself coding a back button in each of these components, I asked myself how could I write DRYer code - a dynamic back button that would send user a page up in the url path:

For instance, if someone is in `/admin/approveusers` back button would bring Users to `/admin`. The same button, when placed in Component sitting in `/admin/allusers` would bring folks to `/admin`.

I started to rummage in the `react-router-dom` properties: `location`, `history`, `match`. I found no property that would contain the existing path minus a level. Maybe I missed it or indeed it doesn't exist (I had to try!). There is a `goBack()` method in history which was interesting. However, it seemed like a bad idea - even though I expect Users to enter the Component that has the back button by parent path, someone may end up in the Component as a result of typing the direct url. In that case, the back button using `goBack()` method in history would create a mess.

I didn't do much research online, and settled with the following. Maybe it is a hack, maybe it is best practice, maybe it's horrible, please let me know in the comments! It works, which is what matters at the end of the day.

I am using the `match.path` `react-router-dom` property, which contains the path of the component: i.e. `/admin/active`. With that, I do the following:

1. I split the string by `/`. As a result, I get an array.
2. I find the last item (the one I want to get rid of).
3. I iterate through the array and filter the item I don't want. Using `.filter`. I get another array.
4. I join the array with '/' and voilà, I get the path one level up i.e. '/admin' instead of '/admin/active'.

See below my component:

```
import React from 'react';
import { Link } from 'react-router-dom';

const BackButton = ({ match }) => {
	const arr = match.path.split('/');
	const currPage = arr[arr.length - 1];
	const parentPath = arr
		.filter((item) => {
			return item !== currPage;
		})
		.join('/');
	return <Link to={parentPath}>{`<-- Back`}</Link>;
};

export default BackButton;
```

**EDIT 03/10/2020**

What if I use the `BackButton` component in the top level of the path (`/`)? In that case, there is not one level up to go back to. I refactored my Component to the following:

```
import React from 'react';
import { Link } from 'react-router-dom';

const BackButton = ({ match, destination }) => {
	let parentPath;
	if (match.path === '/') {
		parentPath = `/${destination}`;
	} else {
		const arr = match.path.split('/');
		const currPage = arr[arr.length - 1];
		parentPath = arr
			.filter((item) => {
				return item !== currPage;
			})
			.join('/');
	}
	return (
		<Link to={parentPath}>
			{match.path === '/'
				? `<-- ${destination.charAt(0).toUpperCase() + destination.slice(1)}`
				: '<-- Back'}
		</Link>
	);
};

export default BackButton;
```

I have added a `destination` prop (that I am defining in the parent Component i.e. `destination='login'`. I collect that destination and I use it when `match.path === '/'`. In that case, I set `parentPath` to `/${destination}` and the text in the link becomes whatever string coming from the `destination` prop with the first letter in capital letter.