I want 2 pages in my Chrome extension. For example: first(default) page with list of users and second with actions for this user.
I want to display second page by clicking on user( ClickableListItem
in my case). I use React and React Router. Here the component in which I have:
class Resents extends React.Component {
constructor(props) {
super(props);
this.handleOnClick = this.handleOnClick.bind(this);
}
handleOnClick() {
console.log('navigate to next page');
const path = '/description-view';
browserHistory.push(path);
}
render() {
const ClickableListItem = clickableEnhance(ListItem);
return (
<div>
<List>
<ClickableListItem
primaryText="Donald Trump"
leftAvatar={<Avatar src="img/some-guy.jpg" />}
rightIcon={<ImageNavigateNext />}
onClick={this.handleOnClick}
/>
// some code missed for simplicity
</List>
</div>
);
}
}
I also tried to wrap ClickableListItem
into Link
component(from react-router
) but it does nothing.
Maybe the thing is that Chrome Extensions haven`t their browserHistory
... But I don`t see any errors in console...
What can I do for routing with React?
While you wouldn't want to use the browser (or hash) history for your extension, you could use a memory history. A memory history replicates the browser history, but maintains its own history stack.
import { createMemoryHistory } from 'history'
const history = createMemoryHistory()
For an extension with only two pages, using React Router is overkill. It would be simpler to maintain a value in state describing which "page" to render and use a switch or if/else statements to only render the correct page component.
render() {
let page = null
switch (this.state.page) {
case 'home':
page = <Home />
break
case 'user':
page = <User />
break
}
return page
}
I know this post is old. Nevertheless, I'll leave my answer here just in case somebody still looking for it and want a quick answer to fix their existing router.
In my case, I get away with just switching from BrowserRouter
to MemoryRouter
. It works like charm without a need of additional memory
package!
import { MemoryRouter as Router } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<OptionsComponent />
</Router>
</React.StrictMode>,
document.querySelector('#root')
);
You can try other methods, that suits for you in the ReactRouter Documentation
I solved this problem by using single routes instead of nested. The problem was in another place...
Also, I created an issue: https://github.com/ReactTraining/react-router/issues/4309
I just had to use createMemoryHistory
instead of createBrowserHistory
:
import React from "react";
import ReactDOM from "react-dom";
import { Router, Switch, Route, Link } from "react-router-dom";
import { createMemoryHistory } from "history";
import Page1 from "./Page1";
import Page2 from "./Page2";
const history = createMemoryHistory();
const App: React.FC<{}> = () => {
return (
<Router history={history}>
<Switch>
<Route exact path="/">
<Page1 />
</Route>
<Route path="/page2">
<Page2 />
</Route>
</Switch>
</Router>
);
};
const root = document.createElement("div");
document.body.appendChild(root);
ReactDOM.render(<App />, root);
import React from "react";
import { useHistory } from "react-router-dom";
const Page1 = () => {
const history = useHistory();
return (
<button onClick={() => history.push("/page2")}>Navigate to Page 2</button>
);
};
export default Page1;
This is a very lightweight solution I just found. I just tried it - simple and performant: react-chrome-extension-router
A modern lightweight option has presented itself with the package wouter
.
You can create a custom hook to change route based on the hash.
see wouter docs .
import { useState, useEffect } from "react";
import { Router, Route } from "wouter";
// returns the current hash location in a normalized form
// (excluding the leading '#' symbol)
const currentLocation = () => {
return window.location.hash.replace(/^#/, "") || "/";
};
const navigate = (to) => (window.location.hash = to);
const useHashLocation = () => {
const [loc, setLoc] = useState(currentLocation());
useEffect(() => {
// this function is called whenever the hash changes
const handler = () => setLoc(currentLocation());
// subscribe to hash changes
window.addEventListener("hashchange", handler);
return () => window.removeEventListener("hashchange", handler);
}, []);
return [loc, navigate];
};
const App = () => (
<Router hook={useHashLocation}>
<Route path="/about" component={About} />
...
</Router>
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.