React中点击按钮获取react-spreadsheet组件数据的实现方法
问题:点击按钮时获取react-spreadsheet组件中的数据
我有一个包含react-spreadsheet组件和按钮的React应用,希望点击“Load Batch Input”按钮时,在loadBatchInput()函数中获取前端添加到电子表格中的数据。现有代码如下:
import * as React from 'react'; import PropTypes from 'prop-types'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import { TextField, Button } from '@mui/material'; import './App.css'; import Spreadsheet from "react-spreadsheet"; import Dropdown from 'react-dropdown'; import 'react-dropdown/style.css'; function TabPanel(props) { const { children, value, index, ...other } = props; return ( <div role="tabpanel" hidden={value !== index} id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other} > {value === index && ( <Box sx={{ p: 3 }}> <Typography>{children}</Typography> </Box> )} </div> ); } function loadBatchInput() { alert("inside"); } function App() { const [tabValue, setValue] = React.useState(0); const handleChange = (event, newValue) => { setValue(newValue); }; //batch input excel const [batchInputData, setbatchInputData] = React.useState([ [{ value: "Type"}, { value: "Region" }, { value: "Product" }, { value: "Brand" }, { value: "Sku_Type" }], [] ]); return ( <div className="App"> <div className="content"> <TabPanel value={tabValue} index={0}> <div className='rowA'> <div> Batch Input Table </div> <div> <Button variant="contained" onClick={() => loadBatchInput() }>Load Batch Input</Button> </div> <div> <Spreadsheet data={batchInputData} onChange={setbatchInputData} /> </div> </div> </TabPanel> </div> </div> ); } export default App;
请问是否有方法实现该需求?
解决方案
当然可以实现,核心问题是当前loadBatchInput函数定义在App组件外部,无法访问组件内部的batchInputData状态。以下两种方式都能解决:
方法一:将loadBatchInput移到组件内部
直接把函数放到App组件里,就能直接读取batchInputData状态:
function App() { const [tabValue, setValue] = React.useState(0); const [batchInputData, setbatchInputData] = React.useState([ [{ value: "Type"}, { value: "Region" }, { value: "Product" }, { value: "Brand" }, { value: "Sku_Type" }], [] ]); const handleChange = (event, newValue) => { setValue(newValue); }; // 移到组件内部,直接访问状态 const loadBatchInput = () => { console.log("表格原始数据:", batchInputData); // 可选:过滤空行,只保留有内容的行 const validData = batchInputData.filter(row => row.some(cell => cell?.value)); alert(JSON.stringify(validData, null, 2)); }; return ( <div className="App"> <div className="content"> <TabPanel value={tabValue} index={0}> <div className='rowA'> <div>Batch Input Table</div> <div> <Button variant="contained" onClick={loadBatchInput}>Load Batch Input</Button> </div> <div> <Spreadsheet data={batchInputData} onChange={setbatchInputData} /> </div> </div> </TabPanel> </div> </div> ); }
方法二:通过参数传递数据给外部函数
如果需要保持loadBatchInput在组件外部,点击按钮时把batchInputData作为参数传入即可:
// 外部函数接收数据参数 function loadBatchInput(data) { console.log("表格原始数据:", data); const validData = data.filter(row => row.some(cell => cell?.value)); alert(JSON.stringify(validData, null, 2)); } function App() { const [tabValue, setValue] = React.useState(0); const [batchInputData, setbatchInputData] = React.useState([ [{ value: "Type"}, { value: "Region" }, { value: "Product" }, { value: "Brand" }, { value: "Sku_Type" }], [] ]); const handleChange = (event, newValue) => { setValue(newValue); }; return ( <div className="App"> <div className="content"> <TabPanel value={tabValue} index={0}> <div className='rowA'> <div>Batch Input Table</div> <div> {/* 点击时传递状态数据 */} <Button variant="contained" onClick={() => loadBatchInput(batchInputData) }>Load Batch Input</Button> </div> <div> <Spreadsheet data={batchInputData} onChange={setbatchInputData} /> </div> </div> </TabPanel> </div> </div> ); }
额外优化:转换数据格式
react-spreadsheet的data是二维对象数组,你可以把它转换成更易处理的键值对格式:
const formattedData = batchInputData.slice(1).map(row => { return { type: row[0]?.value || '', region: row[1]?.value || '', product: row[2]?.value || '', brand: row[3]?.value || '', skuType: row[4]?.value || '' }; }).filter(item => Object.values(item).some(val => val));
内容的提问来源于stack exchange,提问作者SM079
相关产品推荐
相关产品推荐

