【问题标题】:react route - How to use history.push to switch components ? Only URL changesreact route - 如何使用 history.push 切换组件?仅 URL 更改
【发布时间】:2021-09-20 23:54:33
【问题描述】:

我有一个功能,我希望它替换 HeaderFooter 组件之间的组件。
我应该在哪里/如何将defaultRouter 函数与history.push 一起使用。我看到只有 URL 改变了
Header 组件正在更新pageIndex
我尝试将 defaultRouter 更改为 useCallback 函数,但根本没有用。

这些函数的顺序是什么? 应用.js

function App() {
  const [searchResults, setSearchResults] = useState([]);
  const [itemsAmount, setItemsAmount] = useState('');
  const [pageIndex, setPageIndex] = useState();

  const history = createBrowserHistory();

  // let history = useHistory();

  const defaultRouter = useMemo(() => {
    console.log(pageIndex);
    switch (pageIndex) {
      case 1:
        history.push({ pathname: '/search', state: searchResults });
        break;
      case 2:
        history.push('/cart');
        break;
      default:
        history.push('/');
        break;
    }
  }, [pageIndex]);

  return (
    <div className='App'>
      <Header
        settingResults={setSearchResults}
        itemsCartAmount={itemsAmount}
        setPageIndex={setPageIndex}
      />
       {defaultRouter}
       <Footer />
      <Router history={history}>
        <Switch>
          <Route exact path='/'>
            <Home />
          </Route>
          <Route path='/search'>
            <Search/>
          </Route>
          <Route path='/cart'>
            <Cart />
          </Route>
          <Route component={PageNotFound} />;
        </Switch>
      </Router>
     
    </div>
  );
}

编辑

我刚刚从 Index.js 中删除了BrowserRouter,同样的问题。
Index.js

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

pageIndex上方的这种方式正在更新,但history.push不要切换组件。

【问题讨论】:

  • 你能告诉 use 为什么你在你的应用程序中使用 2 个路由器吗?
  • 嗨@kumarmo2,在我之前的问题中,我刚刚删除了Index.js 中的``。同样的问题。

标签: reactjs routes react-router react-router-dom history


【解决方案1】:

我认为这里发生的情况是,每次更新 pageIndex 时都会创建 history 对象。理想情况下,它应该手动创建一次。

您可以在这里找到有效的解决方案Sandbox

我已经更新了

  • 创建历史对象的逻辑
  • 从应用中删除了Router
  • 使用useHistory获取组件中的历史对象。
  • 还编写了pageIndex 更新时推送更改的效果。

【讨论】:

  • 谢谢,我现在正在检查。我有一个问题 - useEffect 将在第一次渲染后再次渲染 Home 组件,我可以阻止吗?
  • 我不确定您为什么使用pageIndex,但我实际上会摆脱pageIndex。单击按钮时,我会直接执行history.push 而不是设置状态。而一旦我们摆脱@​​987654332@,效果也会消失
  • 在我的 Index.js 中,我像你一样用 BrowserRouter 包装了我的应用程序,但只有 URL 发生了变化。
  • 那么当所有路由都在 APP.js 中时,我将如何在 Header 中使用 history.push ?没有pageIndex
  • 如果你注意到,我在任何组件之外创建了history 对象。这确保历史对象只被创建一次。您在 App 中创建历史对象,这意味着任何时候更新状态,都会创建一个新的历史对象
【解决方案2】:

更新

请看看这个,我试图复制你的问题。

https://codesandbox.io/s/amazing-swartz-jxc5p?file=/src/App.js

您已经使用了两次路由器,一次在App.js 内作为&lt;Router&gt;,另一次在index.js 内作为&lt;BrowserRouter&gt;。 你需要做的是;仅在 App.js 中使用并确保将其导入为:

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

因为路由器接受历史道具,而不是浏览器路由器,并且还从 index.js 中删除 BrowserRouter

为了更安全,请使用useHistory() 钩子获取历史值。

这将解决您的问题。

【讨论】:

  • 我从 index.js 中删除了 BrowserRouter,仍然只是 URL 更改为 /search
  • @ExtraSun 请检查更新的答案,我已附上codeandbox的链接。我试图复制你的问题。
  • 使用let history = useHistory() - `return (
    ` 出错TypeError: Cannot read property 'push' of undefined. 你的代码在codesandbox.io只更改 URL 而不是组件。
  • 我检查了它,它也在切换组件。无论如何,您能否使用所有 import 语句更新您的代码,那里可能存在问题。
  • 奇怪,因为点击按钮时我只看到“Sample”,而不是&lt;h1&gt; Cart &lt;/h1&gt;;
猜你喜欢
相关资源
最近更新 更多
热门标签