react页面之间快速传递数据方式
React页面之间快速传递数据方式全解析
导语
在React应用开发中,组件间的数据传递是永恒的话题。当我们需要在不同页面(路由)间传递数据时,选择合适的方式尤为重要。本文将全面剖析React中页面间数据传递的各种方案,帮助开发者根据实际场景选择最佳实践。
核心概念解释
React页面间数据传递主要分为两大类:
- 同路由层级传递:通过props、context等方式
- 跨路由传递:需要借助路由机制或状态管理工具
常用传递方式及使用场景
1. URL参数(适合简单数据)
// 发送方
import { useNavigate } from 'react-router-dom';
function PageA() {
const navigate = useNavigate();
const sendData = () => {
navigate('/pageB?name=张三&id=123');
};
return <button onClick={sendData}>跳转到PageB</button>;
}
// 接收方
import { useLocation } from 'react-router-dom';
function PageB() {
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const name = searchParams.get('name');
const id = searchParams.get('id');
return <div>接收到的数据:{name}, {id}</div>;
}
适用场景:传递少量简单数据,数据可见在URL中
2. 路由状态(适合中等复杂度数据)
// 发送方
import { useNavigate } from 'react-router-dom';
function PageA() {
const navigate = useNavigate();
const sendData = () => {
navigate('/pageB', { state: { user: { name: '李四', age: 25 } } });
};
return <button onClick={sendData}>跳转到PageB</button>;
}
// 接收方
import { useLocation } from 'react-router-dom';
function PageB() {
const location = useLocation();
const { user } = location.state || {};
return (
<div>
用户信息:{user?.name}, {user?.age}
</div>
);
}
适用场景:传递对象等较复杂数据,数据不会暴露在URL中
3. 状态管理(适合复杂应用)
// store.js
import { createStore } from 'redux';
const initialState = {};
function reducer(state = initialState, action) {
switch (action.type) {
case 'SET_PAGE_DATA':
return { ...state, pageData: action.payload };
default:
return state;
}
}
export const store = createStore(reducer);
// PageA.js
import { useDispatch } from 'react-redux';
import { store } from './store';
function PageA() {
const dispatch = useDispatch();
const sendData = () => {
dispatch({
type: 'SET_PAGE_DATA',
payload: { products: ['手机', '电脑'], total: 2 }
});
window.location.href = '/pageB';
};
return <button onClick={sendData}>跳转到PageB</button>;
}
// PageB.js
import { useSelector } from 'react-redux';
function PageB() {
const pageData = useSelector(state => state.pageData);
return (
<div>
商品列表:{pageData?.products?.join(', ')},总数:{pageData?.total}
</div>
);
}
适用场景:大型应用,需要跨多级组件共享状态
4. Context API(适合中等规模应用)
// DataContext.js
import { createContext, useContext, useState } from 'react';
const DataContext = createContext();
export function DataProvider({ children }) {
const [pageData, setPageData] = useState(null);
return (
<DataContext.Provider value={{ pageData, setPageData }}>
{children}
</DataContext.Provider>
);
}
export function usePageData() {
return useContext(DataContext);
}
// PageA.js
import { usePageData } from './DataContext';
function PageA() {
const { setPageData } = usePageData();
const sendData = () => {
setPageData({ message: 'Hello from PageA' });
window.location.href = '/pageB';
};
return <button onClick={sendData}>跳转到PageB</button>;
}
// PageB.js
import { usePageData } from './DataContext';
function PageB() {
const { pageData } = usePageData();
return <div>{pageData?.message}</div>;
}
适用场景:需要避免prop drilling的中等规模应用
方案对比
方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
URL参数 | 简单直接,可分享链接 | 数据暴露,类型受限 | 简单数据,需要分享链接 |
路由状态 | 隐藏数据,支持复杂对象 | 刷新页面可能丢失 | 中等复杂度数据 |
状态管理 | 全局访问,持久化 | 增加复杂度 | 大型应用,复杂状态管理 |
Context API | 避免prop drilling | 可能引起不必要渲染 | 中等规模应用 |
LocalStorage | 持久化,跨会话 | 安全性低,大小限制 | 需要持久化的非敏感数据 |
实战案例:电商网站商品列表到详情页
// ProductList.js
import { useNavigate } from 'react-router-dom';
function ProductList() {
const navigate = useNavigate();
const products = [
{ id: 1, name: 'iPhone 13', price: 5999 },
{ id: 2, name: 'MacBook Pro', price: 12999 }
];
const goToDetail = (product) => {
navigate('/product/detail', {
state: { product },
// 或者使用search: `?id=${product.id}` 简单模式
});
};
return (
<div>
<h2>商品列表</h2>
<ul>
{products.map(p => (
<li key={p.id} onClick={() => goToDetail(p)}>
{p.name} - ¥{p.price}
</li>
))}
</ul>
</div>
);
}
// ProductDetail.js
import { useLocation } from 'react-router-dom';
function ProductDetail() {
const { state } = useLocation();
const { product } = state || {};
if (!product) return <div>商品不存在</div>;
return (
<div>
<h2>{product.name}</h2>
<p>价格: ¥{product.price}</p>
<p>ID: {product.id}</p>
</div>
);
}
小结
在React应用中传递页面数据,没有放之四海而皆准的方案。根据你的具体需求:
- 简单数据且需要可分享 → URL参数
- 中等复杂度且不想暴露数据 → 路由状态
- 大型应用需要集中管理 → Redux等状态管理
- 避免prop drilling → Context API
- 需要持久化 → LocalStorage/SessionStorage
理解每种方式的适用场景和限制,才能在实际开发中做出合理选择,构建出高效可靠的React应用。