You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从React Router传递id/参数至Redux Action?

React Router 传递ID到Redux Action的完整方案

嘿,刚好我之前也处理过类似的需求,给你一步步拆解怎么实现:

1. 先配置带动态参数的路由

首先得在你的路由配置里(比如Home.js或者单独的路由文件)给详情页加上动态ID参数,这样React Router才能捕获到URL里的ID值:

// Home.js 或者路由配置文件
import { Routes, Route } from 'react-router-dom';
import ListingPage from './ListingPage';
import Detail from './Detail';

function Home() {
  return (
    <Routes>
      <Route path="/songs" element={<ListingPage />} />
      {/* 这里的:id就是动态参数,会匹配URL里类似/songs/55的路径 */}
      <Route path="/songs/:id" element={<Detail />} />
    </Routes>
  );
}

export default Home;

同时,在ListingPage.js里的Link要指向正确的动态路径:

// ListingPage.js
import { Link } from 'react-router-dom';

function ListingPage({ songs }) {
  return (
    <div>
      {songs.map(song => (
        <div key={song.id}>
          {/* 把当前对象的id拼到Link的to属性里 */}
          <Link to={`/songs/${song.id}`}>{song.title}</Link>
        </div>
      ))}
    </div>
  );
}

2. 在Detail组件里获取路由参数

用React Router v6的useParams()钩子就能轻松拿到URL里的ID,非常方便:

// Detail.js
import { useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { fetchSongDetail } from './redux/actions/songActions';

function Detail() {
  // 从路由里取出id参数
  const { id } = useParams();
  const dispatch = useDispatch();
  // 从Redux store里获取详情数据、加载状态、错误信息
  const songDetail = useSelector(state => state.songs.detail);
  const isLoading = useSelector(state => state.songs.isLoading);
  const error = useSelector(state => state.songs.error);

  // 组件挂载时,把id传给Redux Action
  useEffect(() => {
    if (id) {
      dispatch(fetchSongDetail(id));
    }
  }, [dispatch, id]); // 依赖项里加上id,防止重复请求

  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>出错了:{error}</div>;

  return (
    <div>
      <h1>{songDetail.title}</h1>
      <p>歌手:{songDetail.artist}</p>
      {/* 其他详情字段 */}
    </div>
  );
}

export default Detail;

3. 编写接收ID参数的Redux Action

接下来要让你的Action能接收id参数,然后拼接成正确的API请求地址:

// redux/actions/songActions.js
import axios from 'axios';

// Action Types
export const FETCH_SONG_DETAIL_REQUEST = 'FETCH_SONG_DETAIL_REQUEST';
export const FETCH_SONG_DETAIL_SUCCESS = 'FETCH_SONG_DETAIL_SUCCESS';
export const FETCH_SONG_DETAIL_FAILURE = 'FETCH_SONG_DETAIL_FAILURE';

// 这里的id就是从Detail组件传过来的参数
export const fetchSongDetail = (id) => {
  return async (dispatch) => {
    dispatch({ type: FETCH_SONG_DETAIL_REQUEST });
    try {
      // 拼接带id的API地址
      const response = await axios.get(`http://127.0.0.1:8000/api/v1/songs/${id}`);
      dispatch({
        type: FETCH_SONG_DETAIL_SUCCESS,
        payload: response.data
      });
    } catch (error) {
      dispatch({
        type: FETCH_SONG_DETAIL_FAILURE,
        payload: error.message
      });
    }
  };
};

4. 对应的Reducer处理(补充)

最后,Reducer要处理这几个Action类型,更新store里的状态:

// redux/reducers/songReducer.js
import {
  FETCH_SONG_DETAIL_REQUEST,
  FETCH_SONG_DETAIL_SUCCESS,
  FETCH_SONG_DETAIL_FAILURE
} from '../actions/songActions';

const initialState = {
  detail: {},
  isLoading: false,
  error: null
};

const songReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_SONG_DETAIL_REQUEST:
      return {
        ...state,
        isLoading: true,
        error: null
      };
    case FETCH_SONG_DETAIL_SUCCESS:
      return {
        ...state,
        isLoading: false,
        detail: action.payload
      };
    case FETCH_SONG_DETAIL_FAILURE:
      return {
        ...state,
        isLoading: false,
        error: action.payload
      };
    default:
      return state;
  }
};

export default songReducer;

几个小提醒

  • 确保你的Redux store已经正确配置,并且Detail组件被包裹在Provider里,否则useDispatch和useSelector会失效。
  • 如果你的React Router是v5或更早版本,获取参数要用props.match.params.id,函数组件可以用useRouteMatch钩子。
  • 可以在useEffect里加个判断,避免id为空时发起无效请求。

内容的提问来源于stack exchange,提问作者Piyal George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:50:37