React中点击Link前完成异步setState的解决方法咨询
问题:React跳转页面时state无法传递到详情页的解决办法
我想捕获用户点击跳转链接时的选择,在详情页展示选中图片的信息。现在遇到的问题是浏览器在React更新state“key”之前就完成了页面跳转,导致key的状态变更没法传递到详情页。求一个不用fetch的简便解决办法。
相关代码
Gallery组件代码
export default class IGallery extends React.Component { constructor(props) { super(props); this.state = { countryList: [], wallet: "", key: "", }; } handleClick = (_key) => { console.log("before setState", this.state.key); this.setState({ key: _key }, () => console.log("after setState", this.state.key) ); }; render() { return ( <div className={styles.gallery}> <h1>Gallery</h1> <ImageList cols={6} rowHeight={320}> {this.state.countryList.map((data, idx) => ( <ImageListItem key={idx} className={styles.imageItem}> <Link to="/item" onClick={() => this.handleClick(data.key)}> <img src={data.image} width={320} /> <ItemDetail id={this.state.key}></ItemDetail> </Link> <ImageListItemBar title="Braintube" subtitle={data.key} actionIcon={<FavoriteBorder fontSize="large" color="pink" />} actionPosition="top" /> </ImageListItem> ))} </ImageList> </div> ); } }
路由配置代码
<Router> <Header childToParent={childToParent}/> <Switch> <Route path="/" exact={true}> <Home></Home></Route> <Route path="/project-space"> <ProjectSpace childToParent={wallet}></ProjectSpace> </Route> <Route path="/about"> <About></About></Route> <Route path="/item"><ItemDetail></ItemDetail></Route> </Switch> <FooterMain></FooterMain> </Router>
解决方案
方法一:通过路由参数传递(最简便)
- 修改
<Link>组件,把选中的data.key作为路由参数拼接在路径中:<Link to={`/item/${data.key}`}> <img src={data.image} width={320} /> </Link> - 更新路由配置,添加参数占位符
:key:<Route path="/item/:key"><ItemDetail></ItemDetail></Route> - 在
ItemDetail组件中获取参数:- React Router v5:通过
props.match.params.key获取class ItemDetail extends React.Component { render() { const { key } = this.props.match.params; return <div>选中的图片key:{key}</div>; } } - React Router v6:使用
useParams()钩子获取import { useParams } from 'react-router-dom'; function ItemDetail() { const { key } = useParams(); return <div>选中的图片key:{key}</div>; }
- React Router v5:通过
方法二:通过路由state属性传递
- 在
<Link>的to属性中直接携带state数据:<Link to={{ pathname: '/item', state: { key: data.key } }}> <img src={data.image} width={320} /> </Link> - 在
ItemDetail组件中获取state:- React Router v5:通过
props.location.state.key获取class ItemDetail extends React.Component { render() { const { key } = this.props.location.state || {}; return <div>选中的图片key:{key}</div>; } } - React Router v6:使用
useLocation()钩子获取import { useLocation } from 'react-router-dom'; function ItemDetail() { const location = useLocation(); const { key } = location.state || {}; return <div>选中的图片key:{key}</div>; }
- React Router v5:通过
原代码问题说明
原代码把<ItemDetail>放在了<Link>内部,这本身逻辑错误——Gallery页面不需要渲染详情组件;另外setState是异步操作,点击Link后浏览器会立刻跳转页面,state还没完成更新就已经离开当前页面,自然无法传递数据。
内容的提问来源于stack exchange,提问作者cbox
相关产品推荐
相关产品推荐

