You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React/Redux(DVA)中如何将URL与Action关联绑定?

解决URL与Action关联的方案

在DVA框架里,要实现URL变更绑定Action,同时支持直接访问URL触发对应逻辑,需要从路由配置组件生命周期监听两方面入手,下面是具体步骤:

1. 配置动态路由

首先在你的路由配置文件(一般是router.js)里,把/f/:id这个动态路由和对应的组件绑定好,确保DVA能正确匹配到该路由并渲染目标组件:

import { Router, Route } from 'dva/router';
import YourComponent from './routes/YourComponent';

function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Route path="/f/:id" component={YourComponent} />
      {/* 其他路由... */}
    </Router>
  );
}

export default RouterConfig;

2. 在组件中监听路由参数,触发对应Action

从你的代码看你用的是类组件,需要在组件挂载路由参数更新两个时机,读取URL中的id并dispatch对应的Action:

(1)组件挂载时触发Action

componentDidMount生命周期中,从match.params获取id,然后调用加载数据的Action:

componentDidMount() {
  const { match, dispatch } = this.props;
  const { id } = match.params;
  // 替换成你实际的加载Action,比如获取对应id的内容
  dispatch({
    type: 'yourModel/fetchTargetContent',
    payload: { id },
  });
}

(2)路由参数变化时重新触发Action

当你通过routerRedux.push('/f/' + record.id)跳转到不同的id时,组件不会重新挂载,所以需要在componentDidUpdate中对比前后的路由参数,变化时重新触发Action:

componentDidUpdate(prevProps) {
  const { match, dispatch } = this.props;
  const prevId = prevProps.match.params.id;
  const currentId = match.params.id;
  // 如果id发生变化,重新加载对应内容
  if (currentId !== prevId) {
    dispatch({
      type: 'yourModel/fetchTargetContent',
      payload: { id: currentId },
    });
  }
}

3. 补充说明

你之前用的dispatch(routerRedux.push('/f/' + record.id))是正确的跳转方式,它会修改URL并触发路由匹配,现在结合上面的生命周期监听,就能在跳转后自动触发对应的Action加载内容;而当用户直接访问/f/xxx时,组件挂载时会自动读取参数并触发Action,刚好满足你的需求。

如果后续换成函数组件+hooks,也可以用useEffect监听match.params.id的变化,逻辑是类似的:

import { useEffect } from 'react';

function YourComponent({ match, dispatch }) {
  const { id } = match.params;

  useEffect(() => {
    dispatch({
      type: 'yourModel/fetchTargetContent',
      payload: { id },
    });
  }, [id, dispatch]);

  // 组件渲染逻辑...
}

内容的提问来源于stack exchange,提问作者mokiliii Lo

火山引擎 最新活动