点击提交按钮后如何重置输入值


import React, { useState } from 'react';
import './StockQuotes.css'; 
import { createMuiTheme, withStyles, makeStyles, ThemeProvider } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
import stockData from '../util/stockData';
import { useDispatch } from 'react-redux';
import { getStocksOwned } from '../slices/stocksOwnedSlice';
const StockQuotes = () => {
const [sharesToBuy, setSharesToBuy] = useState(stockData);
const dispatch = useDispatch();

const handleChange = (event, index) => {
stockData[index].owned = parseInt(event.target.value);
setSharesToBuy(stockData);
}

const handleClick = (event, index) => {
event.preventDefault();
dispatch(getStocksOwned(sharesToBuy));
stockData[index].owned = 0;
}
const StyledTableCell = withStyles((theme) => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
body: {
fontSize: 14,
},
}))(TableCell);
const StyledTableRow = withStyles((theme) => ({
root: {
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
},
}))(TableRow);
const useStyles = makeStyles((theme) => ({
margin: {
margin: theme.spacing(1),
},
table: {
minWidth: 700,
},
}));
const classes = useStyles();
const theme = createMuiTheme({
palette: {
primary: {main: '#00e676'},
},
});
return(
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell>Stock Name</StyledTableCell>
<StyledTableCell align="right">Current Price</StyledTableCell>
<StyledTableCell align="right">Shares</StyledTableCell>
<StyledTableCell align="right">Order</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{stockData.map((stock, index) => (
<StyledTableRow key = {index} >
<StyledTableCell component="th" scope="row">
{stock.name}
</StyledTableCell>
<StyledTableCell align="right">${stock.price}</StyledTableCell>
<StyledTableCell align="right"><input type="number" onChange={event => handleChange(event, index)}></input></StyledTableCell>
<StyledTableCell align="right">
<ThemeProvider theme={theme}>
<Button variant="contained" color="primary" className={classes.margin} onClick={event => handleClick(event, index)}>
BUY
</Button>
</ThemeProvider>
</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
)
}
export default StockQuotes;

单击"提交"按钮后,我正试图将stockData[index].归为0。通常是直接的,但这次通过映射包含8个对象的stockDatajson文件创建了8个输入字段。所以,如果我把value属性放在input标记中,然后键入,整个8个输入字段都会改变。所以我用这种方式编码,除非在我点击后,我得到";TypeError:无法分配给对象"#"的只读属性"owned";。我能做什么?

这里发生了一些事情:

  1. stockData似乎只是用于设置组件状态的初始值。初始化状态后,更新并读取sharesToBuy,以便这些更改流到组件树中
  2. 不要改变对象/状态。这可能会导致错误,并阻止您的组件正确更新。相反,创建一个具有更新值的新副本
  3. 控制您的input,并根据状态更改更新value
// Convenience function for updating state.
const updateOwnedValue = (index, owned) => {
// Instead of mutating the array/object, create a copy with the updated values
// and then update state so the changes flow down to your components.
const newState = sharesToBuy.map((stock, idx) => (
idx === index ? { ...stock, owned } : stock
));
setSharesToBuy(newState);
};
const handleChange = (event, index) => {
updateOwnedValue(index, parseInt(event.target.value));
}
const handleClick = (event, index) => {
event.preventDefault();
dispatch(getStocksOwned(sharesToBuy));
updateOwnedValue(index, 0);
}
...
// Iterate over component state instead of the imported value.
{sharesToBuy.map((stock, index) => (
...
<input
type="number"
onChange={event => handleChange(event, index)}
value={
// This makes your input a controlled component.
// The value will respond to state changes.
stock.owned
}
/>
...
))}

在handleClick函数中,最后重置您的setSharesToBuy

类似地,setSharesToBuy(''(;

清除输入

为了在点击提交时重置输入,您希望输入是一个受控组件。这意味着is的值来自于您向它传递value道具,而不是将其存储在本地。然后,提交事件的处理程序将负责将该值设置为0。

Material UI同时支持受控和非受控组件,因此这应该是一个简单的更改,但由于应用程序中数据的混乱控制,它变得更加复杂。这个输入值是从哪里来的?需要更改哪个值才能将其设置为0?

数据结构

您需要考虑存在哪些数据以及数据存储在哪里。json文件中的数据应该使用一次来填充应用程序或其redux存储的initialState,就这样

现在,您实际上正在更改从json文件导入的stockData值。这真是糟糕的设计。

您可以有一些存储在redux中的信息和一些存储在本地组件状态中的信息,但这两个位置的数据不应该相同。本地状态将用于本地更改,例如在点击"之前在表格中输入的数字;购买";按钮而每只股票的当前价格应存储在redux中,并通过useSelector访问。

这次修订并不完美,但希望它能让你走上正轨。

嵌套组件

在我链接到上面的演示中,您可能会注意到,当您键入字符时,输入组件会失去焦点。发生这种情况的原因是您在StockQuotes组件中定义了组件StyledTableCellStyledTableRow。这意味着,每当状态发生变化时,都会重新创建这些组件。输入不被视为相同的输入,因为它所在的表单元格是不同的表单元格,这就是它失去焦点的原因。

您希望将样式化的组件定义为StockQuotes组件之外的顶级组件。(我试着把它们复制粘贴到外面,但这带来了其他错误。作为一个临时的破解解决方案,你可以useMemo来避免重新创建,但这并不理想。(

相关内容

  • 没有找到相关文章

最新更新