reactjs 如何使用useNavigate with React & Redux [duplicate]

eaf3rand  于 2023-05-17  发布在  React
关注(0)|答案(1)|浏览(185)

此问题已在此处有答案

react router v6 navigate outside of components(7个回答)
5小时前关闭
我正在更新一个React with redux应用程序,以使用react-router-dom v6。
在应用程序中,我有一个用于浏览器历史记录的帮助文件:

_helpers.history.ts

import { createBrowserHistory } from 'history';

  export const history = createBrowserHistory();

我在我的user.actions.js文件中使用它来在登录、注册等之后将用户导航到新视图。

user.actions.js

import { history } from '../_helpers';

export const userActions = {
    login,
    logout,
    register,
    getAll,
    delete: _delete
};

function login(username, password, from) {
    return dispatch => {
        dispatch(request({ username }));

        userService.login(username, password)
            .then(
                user => { 
                    dispatch(success(user));
                    history.push('/dashboard');
                },
                error => {
                    dispatch(failure(error.toString()));
                    dispatch(alertActions.error(error.toString()));
                }
            );
    };

我将createBrowserHistory替换为react-router-dom中的useNavigate

history.js(已更新)

import { useNavigate } from "react-router-dom";

export const history = useNavigate();

在 * user.actions.js * 中,history.push('/dashboard');被替换为navigate(dashboard)
但是,尝试执行此操作会产生以下错误:

ERROR in [eslint] 
src/_helpers/history.js
  Line 3:24:  React Hook "useNavigate" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function

我还在App.js文件中使用了_helpers.history.js:APP.JS

import { history } from "./_helpers";

function App() {
  return (
    <>
      <Routes history={history}>
        {/* Public Pages */}
        <Route exact path="/" element={<HomePage />} />

我已经看了几个S/O的答案,但它们都与使用功能组件的应用程序有关。在这种情况下,更新helper文件的正确方法是什么?

toiithl6

toiithl61#

useNavigate只能在组件内部调用,并且在路由器的上下文中调用。我认为你想要的是从外部调用history,这在react-router v6中是不支持的。但它可以通过定制路由器来实现。就像这样:

// customRouter 
import { Router } from 'react-router-dom';
import { useRef, useState, useLayoutEffect } from 'react';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

export function CustomRouter({ basename, children }) {
  const historyRef = useRef(customHistory);
  if (historyRef.current == null) {
    historyRef.current = customHistory;
  }
  const myHistory = historyRef.current;
  const [state, setState] = useState({
    action: myHistory.action,
    location: myHistory.location,
  });

  useLayoutEffect(() => myHistory.listen(setState), [myHistory]);

  return (
    <Router
      basename={basename}
      // eslint-disable-next-line react/no-children-prop
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={myHistory}
    />
  );
}

然后用CustomRouter Package 您的组件。就像这样:

const App = () => {
  return (
    <CustomRouter>
      // ... your routes here
    </CustomRouter>
  )
}

你可以在任何地方调用历史。

相关问题