用 React 编写的 Chrome 扩展中的路由

问题描述 投票:0回答:8

我想要我的 Chrome 扩展程序中有 2 个页面。例如:第一个(默认)页面包含用户列表,第二个页面包含该用户的操作。

我想通过单击用户来显示第二页(在我的例子中是

ClickableListItem
)。我使用 React 和 React Router。这是我拥有的组件:

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

我还尝试将

ClickableListItem
包装到
Link
组件(来自
react-router
),但它什么也没做。

也许问题是 Chrome 扩展没有

browserHistory
...但我在控制台中没有看到任何错误...

使用 React 进行路由可以做什么?

javascript reactjs google-chrome-extension react-router url-routing
8个回答
34
投票

我知道这篇文章已经很旧了。尽管如此,我将在这里留下我的答案,以防有人仍在寻找它并想要一个快速答案来修复他们现有的路由器。

就我而言,我只要从

BrowserRouter
切换到
MemoryRouter
就可以了。它就像魅力一样,不需要额外的
memory
包!

import { MemoryRouter as Router } from 'react-router-dom';

ReactDOM.render(
    <React.StrictMode>
        <Router>
            <OptionsComponent />
        </Router>
    </React.StrictMode>,
    document.querySelector('#root')
);

您可以在ReactRouter文档

中尝试其他适合您的方法

13
投票

虽然您不想在扩展程序中使用浏览器(或哈希)历史记录,但您可以使用内存历史记录。内存历史记录复制浏览器历史记录,但维护自己的历史记录堆栈。

import { createMemoryHistory } from 'history'
const history = createMemoryHistory()

对于只有两个页面的扩展,使用 React Router 就有点大材小用了。维护一个描述要渲染哪个“页面”的状态值并使用 switch 或 if/else 语句仅渲染正确的页面组件会更简单。

render() {
  let page = null
  switch (this.state.page) {
  case 'home':
    page = <Home />
    break
  case 'user':
    page = <User />
    break
  }
  return page
}

5
投票

我通过使用单个路由而不是嵌套路由解决了这个问题。问题出在另一个地方......

另外,我创建了一个问题:https://github.com/ReactTraining/react-router/issues/4309


1
投票

这是我刚刚发现的一个非常轻量级的解决方案。我刚刚尝试过 - 简单且高效:

react-chrome-extension-router


1
投票

我只需使用

createMemoryHistory
而不是
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;


1
投票

现代轻量级选项已经随包装一起出现了

wouter

您可以创建自定义挂钩来根据哈希值更改路由。

参见 wouter 文档

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

0
投票

我通过运行

npm eject
并创建第二个
home.html
文件解决了这个问题。

我在以下 Github 存储库中为想要使用 React 开发 chrome 扩展的任何人制作了入门代码react-chrome-extension-template

起始代码包含弹出页面

index.html
和主页
home.html
以及弹出页面中到主页的导航按钮。


0
投票

here is my index.js

root.render(
  <StrictMode>
    <Provider store={store} >
      <PersistGate persistor={persistor}>
        <HashRouter>
          <ChakraProvider theme={theme}>
            <ColorModeScript />
            <App />
          </ChakraProvider>
        </HashRouter>
      </PersistGate>
    </Provider>

  </StrictMode>
);



and here is app js

 <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>


© www.soinside.com 2019 - 2024. All rights reserved.