Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

javascript - How to reset input value after clicking submit button?

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;

I'm trying to get stockData[index].owned to 0 after I click submit button. Usually straight forward, but this time 8 input fields are created through mapping stockData json file which contains 8 objects. So if I put value property by input tag then type, entire 8 input field changes. So I coded this way except after I click, I get "TypeError: Cannot assign to read only property 'owned' of object '#'". What can I do?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A few things going on here:

  1. stockData appears to just be an initial value for setting the component state. Once state is initialized, update and read from sharesToBuy so those changes flow to your component tree.
  2. Don't mutate objects/state. That can cause bugs and prevent your component from updating properly. Instead, create a new copy with updated values.
  3. Make your input controlled and update the value based on state changes.
// 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
    }
  />
  ...
))}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...