Skip to content

同步路由

为了将 dva.js 的路由状态同步到 Redux store 中,你可以使用 connected-react-router 库来实现。这使得你可以在全局 state 中保存路由信息,并且能够更方便地在应用的不同部分访问和操作这些信息。下面是具体的步骤,教你如何在 dva.js 项目中集成 connected-react-router 并同步路由状态到 store。

步骤

1. 安装依赖

首先,你需要安装 connected-react-routerreact-router-dom(如果你还没有安装的话):

bash
npm install connected-react-router react-router-dom
# 或者
yarn add connected-react-router react-router-dom

2. 创建 History 对象

创建一个 history 对象,这个对象将被传递给 connected-react-routerreact-router

javascript
// src/utils/history.js
import { createBrowserHistory } from "history";

export const history = createBrowserHistory();

3. 配置 dva 应用并集成 connected-react-router

接下来,在你的 dva 应用配置中引入 history 对象,并通过 connectRouter 将路由状态连接到 store。

示例:配置 dva 应用

javascript
// src/index.js
import dva from "dva";
import { connectRouter, routerMiddleware } from "connected-react-router";
import createHistory from "./utils/history";
import "./index.css"; // 引入样式文件

const { history } = createHistory();

// 1. 创建 dva 应用实例
const app = dva({
  history,
  // 添加中间件以处理路由动作
  onAction: [routerMiddleware(history)],
});

// 2. 扩展根 reducer 来包含路由状态
app.model(require("./models/example").default);
app._store.replaceReducer(connectRouter(history)(app._store.asyncReducers));

// 3. 定义路由
app.router(() => (
  <ConnectedRouter history={history}>
    {/* 这里放置你的路由配置 */}
  </ConnectedRouter>
));

// 4. 启动应用
app.start("#root");

注意这里的 replaceReducer 调用,它用于将 connected-react-router 的 reducer 添加到现有的 dva reducers 中。

4. 包装 Router 组件

然后,你需要用 ConnectedRouter 替换 BrowserRouterHashRouter。这一步确保了所有的路由变化都会同步到 Redux store。

示例:定义路由

javascript
// src/router.config.js
import React from "react";
import { Route, Switch } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";

function routerConfig() {
  return (
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
    </Switch>
  );
}

export default routerConfig;

src/index.js 中引用此配置:

javascript
app.router(() => (
  <ConnectedRouter history={history}>{routerConfig()}</ConnectedRouter>
));

5. 访问路由状态

现在,你可以在任何连接到 Redux store 的组件中访问路由状态。例如,使用 useSelector Hook:

示例:显示当前路径

javascript
// src/components/LocationDisplay.jsx
import React from "react";
import { useSelector } from "dva";

function LocationDisplay() {
  const location = useSelector((state) => state.router.location);

  return <div>Current Path: {location.pathname}</div>;
}

export default LocationDisplay;

6. 派发导航动作

你可以使用 connected-react-router 提供的辅助函数来派发导航动作,如 pushreplacegoBack 等。由于 dva.js 已经封装了 dispatch,你可以直接使用 dvadispatch 方法来触发这些动作。

示例:导航到新路径

javascript
// src/components/NavigationButton.jsx
import React from "react";
import { useDispatch } from "dva";

function NavigationButton() {
  const dispatch = useDispatch();

  const handleNavigate = () => {
    dispatch({
      type: "@@router/CALL_HISTORY_METHOD",
      payload: { method: "push", args: ["/new-path"] },
    });
  };

  return <button onClick={handleNavigate}>Go to New Path</button>;
}

export default NavigationButton;

这里我们使用了 @@router/CALL_HISTORY_METHOD action 类型来调用 history.push 方法,这是 connected-react-router 推荐的方式。

总结

通过以上步骤,你可以成功地将 dva.js 的路由状态同步到 Redux store 中,从而在整个应用程序中共享和管理路由信息。这对于需要精细控制路由行为或实现复杂导航逻辑的应用来说非常有用。

Released under the MIT License.