React-Router V6中点击按钮用useState无法实现页面间数据传递
React-Router V6跳转传参时useState未更新的问题解决
点击按钮触发函数更新useState,再通过React-Router V6跳转至详情页传递数据时,始终传递空对象,手动赋值useState可以正常工作,但这种写法不够高效且不符合规范。
相关代码片段
父页面按钮代码
<div className="toggleButtons" key={id}> <Link to="/DetailsPage" onClick={toggledItem} state={{ data: data }} className="primary-ff boxyButton" > {buttonText} </Link> <a href={link} className="icon-link" target="_blank"> <i className="fa-solid fa-arrow-up-right-from-square"></i> </a> </div>
useState更新逻辑代码
const softiesInfo = pageContentList.find(({id}) => id == 1); const palcoInfo = pageContentList.find(({id}) => id == 2); const tlaxInfo = pageContentList.find(({id}) => id == 3); const [data, setData] = useState({}) const toggledItem = () => { if (id === 1) { setData(softiesInfo); } else if (id === 2) { setData(palcoInfo) } else { setData(tlaxInfo) } };
详情页渲染代码
export default function DetailsPage() { const location = useLocation(); const data = location.state; return ( <div className="header-wrap"> <h1 className="primary-ff">{data.title}</h1> <img src={data.logoImg} alt={data.altLogo} /> </div> ) });
手动赋值的可行(但不推荐)写法
const [data, setData] = useState({ sectionName: "softies-section", title: "Softies Ice Cream-Under The Scoop", logoImg: softieslogo, altLogo: "softies-logo", img: softiesPlanner, altImg: "Career Day At Pinnacle", img2: softiesAccordion, constrainContent: "lorem a;sdkfj;alskdjfa lksdfjlaksjdl;fkjasldk;fjaslkdfjal;sdkjfalksdjf;laks;dj asflsngealj sflsdajflkads", id: 1, });
问题原因
React的setState是异步执行的,点击Link时,onClick中的setData还未完成状态更新,跳转已经触发,此时传递的data仍是初始的空对象。
解决方案
方案1:直接传递目标数据(推荐)
无需借助useState中转,直接在Link的state中根据id传入对应数据:
<div className="toggleButtons" key={id}> <Link to="/DetailsPage" state={{ data: id === 1 ? softiesInfo : id === 2 ? palcoInfo : tlaxInfo }} className="primary-ff boxyButton" > {buttonText} </Link> <a href={link} className="icon-link" target="_blank"> <i className="fa-solid fa-arrow-up-right-from-square"></i> </a> </div>
方案2:使用useNavigate手动控制跳转
如果必须保留useState,可以用useNavigate替代Link的默认跳转,确保数据正确传递:
import { useNavigate } from 'react-router-dom'; // 组件内部 const navigate = useNavigate(); const [data, setData] = useState({}) const toggledItem = () => { const targetData = id === 1 ? softiesInfo : id === 2 ? palcoInfo : tlaxInfo; setData(targetData); // 直接使用targetData跳转,无需等待setState异步更新 navigate("/DetailsPage", { state: { data: targetData } }); };
同时将Link替换为普通按钮:
<button onClick={toggledItem} className="primary-ff boxyButton"> {buttonText} </button>
内容的提问来源于stack exchange,提问作者ang.jr57
相关产品推荐
相关产品推荐

