React Hooks如何实现不同URL路径下组件之间的state传递?
React Hooks 实现跨路由组件状态传递方案
以下方案默认基于 react-router-dom v6 实现,这是React生态中最常用的路由管理库。
方案1:路由路径参数传参
适合传递非敏感、可公开的短文本内容,刷新页面数据不会丢失
步骤1:配置路由带参数
// 路由配置文件 import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import Home from './Home'; import Info from './Info'; const router = createBrowserRouter([ { path: '/', element: <Home /> }, { path: '/info/:userName?', element: <Info /> }, // ?表示参数为可选 ]); export default function App() { return <RouterProvider router={router} />; }
步骤2:Home组件跳转带参
// Home.jsx import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; export default function Home() { const [inputName, setInputName] = useState(''); const navigate = useNavigate(); const handleSubmit = (e) => { e.preventDefault(); if (inputName.trim()) { // 编码处理避免特殊字符异常 navigate(`/info/${encodeURIComponent(inputName.trim())}`); } }; return ( <form onSubmit={handleSubmit}> <input type="text" value={inputName} onChange={(e) => setInputName(e.target.value)} placeholder="请输入姓名" /> <button type="submit">提交</button> </form> ); }
步骤3:Info组件取参数
// Info.jsx import { useParams } from 'react-router-dom'; export default function Info() { const { userName } = useParams(); const showName = userName ? decodeURIComponent(userName) : '未输入姓名'; return <h1>你输入的姓名是:{showName}</h1>; }
方案2:state隐式传参
适合不想将参数暴露在URL的场景,刷新页面后数据会丢失
步骤1:基础路由配置
const router = createBrowserRouter([ { path: '/', element: <Home /> }, { path: '/info', element: <Info /> }, ]);
步骤2:Home组件跳转传state
// 修改Home组件的handleSubmit方法 const handleSubmit = (e) => { e.preventDefault(); if (inputName.trim()) { navigate('/info', { state: { userName: inputName.trim() } }); } };
步骤3:Info组件取state
// Info.jsx import { useLocation } from 'react-router-dom'; export default function Info() { const location = useLocation(); const showName = location.state?.userName || '未输入姓名'; return <h1>你输入的姓名是:{showName}</h1>; }
方案3:全局状态+本地持久化
适合多页面共享状态、要求刷新不丢失且不暴露参数的复杂场景
步骤1:创建全局状态上下文
// UserContext.js import { createContext, useContext, useState, useEffect } from 'react'; const UserContext = createContext(); export function UserProvider({ children }) { // 初始化从本地存储取数,避免刷新丢失 const [userName, setUserName] = useState(() => localStorage.getItem('userName') || ''); // 状态变化同步到本地存储 useEffect(() => { userName ? localStorage.setItem('userName', userName) : localStorage.removeItem('userName'); }, [userName]); return ( <UserContext.Provider value={{ userName, setUserName }}> {children} </UserContext.Provider> ); } // 自定义Hook简化调用 export function useUser() { return useContext(UserContext); }
步骤2:根组件包裹Provider
import { UserProvider } from './UserContext'; export default function App() { return ( <UserProvider> <RouterProvider router={router} /> </UserProvider> ); }
步骤3:Home组件存状态
// Home.jsx import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useUser } from './UserContext'; export default function Home() { const [inputName, setInputName] = useState(''); const { setUserName } = useUser(); const navigate = useNavigate(); const handleSubmit = (e) => { e.preventDefault(); if (inputName.trim()) { setUserName(inputName.trim()); navigate('/info'); } }; // 表单部分代码和之前一致 return ( <form onSubmit={handleSubmit}> <input type="text" value={inputName} onChange={(e) => setInputName(e.target.value)} placeholder="请输入姓名" /> <button type="submit">提交</button> </form> ); }
步骤4:Info组件取状态
// Info.jsx import { useUser } from './UserContext'; export default function Info() { const { userName } = useUser(); return <h1>你输入的姓名是:{userName || '未输入姓名'}</h1>; }
内容的提问来源于stack exchange,提问作者Arpan Khandelwal
相关产品推荐
相关产品推荐

