React+Redux如何通过按钮实现组件间数据传递并正确渲染
报错核心原因&修复步骤
你遇到的TypeError: Cannot read property 'props' of undefined报错主要来自App.js的错误路由配置,同时现有逻辑也不符合「点击传随机商品到账单页」的需求,按以下步骤修改即可:
第一步:修复App.js路由(直接解决报错)
react-router的Route组件指定component属性后,嵌套的子组件不会作为props传递,你额外写的<BillList items={items}/>完全多余,且App未连接Redux,拿到的items本身就是undefined,反而触发报错。
修改后代码:
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom' import Items from './你的Items组件路径' import BillList from './你的BillList组件路径' function App() { function ItemPost() { let { id } = useParams(); return <div style={{ fontSize: "50px" }}> Now showing post {id} </div>; } return ( <Router> <div className="app"> <main> <Switch> <Route exact path="/" component={Items} /> <Route exact path="/bills/:id?" component={BillList} /> </Switch> </main> </div> </Router> ); } export default App
第二步:修改Items页逻辑,实现跳转带随机商品ID
现有handleClick无实际作用,我们需要拿到随机商品ID通过路由参数传递,同时避免修改Redux原数组:
// 修改随机获取逻辑,浅拷贝数组避免修改原Redux数据 function getRandomElt() { const itemsCopy = [...(items?.items || [])] return itemsCopy.sort(() => Math.random() - Math.random())[0]; } // 无数据时阻止跳转 function handleClick(e){ if(!items?.items?.length) { e.preventDefault() alert('暂无商品数据,请稍后重试') } } // 修改Link跳转路径,拼接随机商品ID const randomItem = getRandomElt() // ... 其他原有JSX不变 <Link onClick={handleClick} to={randomItem ? `/bills/${randomItem.id}` : '/bills'} > <button className="btn btn-primary">Analyse Receipt</button> </Link> // ... 其他原有JSX不变
第三步:修改BillList页,仅展示对应ID的商品
现有账单页是遍历所有商品,不符合需求,我们从路由参数拿ID匹配对应商品即可:
function BillList ({ getItems ,items}){ // ... 原有状态、子组件代码不变 const { id } = useParams(); // 匹配对应ID的商品,ID如果是字符串类型就去掉Number转换 const currentItem = items?.items?.find(item => item.id === Number(id)) || null return( <div className='bills'> <h1>Product id: {id}</h1> <div className='title' style={{textAlign:'center', justifyContent: "center", alignItems: "center", fontSize: 14, }}> <h1>Bakery</h1> <h1>Company Gbr</h1> <h1>Oranienburger Straße 120</h1> <h1>10119 Berlin</h1> </div> <div className="bills-container"> <div className="bill-number"> {currentItem ? ( <React.Fragment key={currentItem.id}> <div className="bill-number"> <h3 > <strong>Bill: </strong>{currentItem.billNumber}</h3> </div> <div style={{flex: 1,textAlign: 'right'}} className="time-date"> <h3> <strong>Time: </strong>{currentItem.created_datetime}</h3> </div> ---------------------------------- <div> <h3 > <Display message={counter}/>x <strong>Title: </strong>{currentItem.title}</h3> <ButtonIncrement className="increase" onClickFunc={incrementCounter}/> <ButtonDecrement className="decrease" onClickFunc={decrementCounter}/> </div> <div style={{textAlign: 'right'}} > <h3> <strong>Price: </strong> {currentItem.price}</h3> </div> <div> <span>Total: {(currentItem.price * counter).toFixed(2)}</span> </div> </React.Fragment> ) : ( <p style={{textAlign: 'center'}}>暂无对应商品数据</p> )} </div> </div> <div className="button" style={{textAlign:"center"}}> <Link to='/'> <button>返回首页</button> </Link> </div> </div> ) }
内容的提问来源于stack exchange,提问作者karim Salim
相关产品推荐
相关产品推荐

