NextJS中非父子组件点击按钮传递props的实现方法
在Next.js(本质是React)里处理这种非父子组件的通信,最直接且轻量的方案就是状态提升——把共享状态放到它们的共同父组件(也就是你的orders.js)里,通过props传递回调和数据。下面是具体实现步骤:
方案一:类组件版本(匹配你当前的代码风格)
1. 更新父组件 orders.js
添加状态管理选中的订单号,同时给Order组件传递点击回调,给OrderViewer组件传递选中的订单号:
import React, { Component } from 'react'; import Order from './Order'; import OrderViewer from './OrderViewer'; class Orders extends Component { // 初始化状态,存储选中的订单号 state = { selectedOrderno: null }; // 定义回调函数,接收子组件传来的订单号并更新状态 handleViewOrder = (orderno) => { this.setState({ selectedOrderno: orderno }); }; render() { return ( <div> <div> <Order orderno='abc' title='abc' status='abc' entity='abc' po='abc' duedate='abc' onViewOrder={this.handleViewOrder} // 传递点击回调 /> {/* 如果有多个Order组件,循环渲染时每个都传这个回调即可 */} </div> <div> <OrderViewer selectedOrderno={this.state.selectedOrderno} /> </div> </div> ); } } export default Orders;
2. 修改 Order.js
给按钮绑定点击事件,触发父组件传递的回调并传入当前组件的订单号:
import React, { Component } from 'react'; class Order extends Component { render() { const { orderno, title, entity, po, duedate, onViewOrder } = this.props; return ( <div> {/* 点击按钮时调用回调,传入当前订单号 */} <button onClick={() => onViewOrder(orderno)}>View Order</button> <p><span>{orderno}</span> <span>{title}</span></p> <p>{entity} - {po}</p> <p>Due {duedate}</p> </div> ); } } export default Order;
3. 修改 OrderViewer.js
接收父组件传递的选中订单号,根据状态展示内容:
import React, { Component } from 'react'; class OrderViewer extends Component { render() { const { selectedOrderno } = this.props; return ( <div> {selectedOrderno ? ( <p>Selected Order Number: {selectedOrderno}</p> ) : ( <p>Click "View Order" to see details</p> )} </div> ); } } export default OrderViewer;
方案二:函数组件版本(Next.js 13+ 推荐写法)
如果你的项目已经使用函数组件+Hook,可以用useState实现同样的逻辑:
orders.js(函数组件)
'use client'; // App Router 模式下需要添加这个指令 import { useState } from 'react'; import Order from './Order'; import OrderViewer from './OrderViewer'; export default function Orders() { const [selectedOrderno, setSelectedOrderno] = useState(null); const handleViewOrder = (orderno) => { setSelectedOrderno(orderno); }; return ( <div> <div> <Order orderno='abc' title='abc' status='abc' entity='abc' po='abc' duedate='abc' onViewOrder={handleViewOrder} /> </div> <div> <OrderViewer selectedOrderno={selectedOrderno} /> </div> </div> ); }
Order.js(函数组件)
export default function Order({ orderno, title, entity, po, duedate, onViewOrder }) { return ( <div> <button onClick={() => onViewOrder(orderno)}>View Order</button> <p><span>{orderno}</span> <span>{title}</span></p> <p>{entity} - {po}</p> <p>Due {duedate}</p> </div> ); }
OrderViewer.js(函数组件)
export default function OrderViewer({ selectedOrderno }) { return ( <div> {selectedOrderno ? ( <p>Selected Order Number: {selectedOrderno}</p> ) : ( <p>Click "View Order" to see details</p> )} </div> ); }
补充说明
如果你的组件层级很深,或者需要全局共享订单状态,可以考虑使用React Context或者Redux/TanStack Query这类状态管理工具,但对于当前场景,状态提升是最简洁高效的方案,不需要引入额外依赖。
内容的提问来源于stack exchange,提问作者Pavindu
相关产品推荐
相关产品推荐

