【问题标题】:React input field lose focus after typing one number输入一个数字后反应输入字段失去焦点
【发布时间】:2021-01-29 00:29:46
【问题描述】:

目前,只要我输入一个数字,输入字段就会失去焦点。所以我拿了 shareToBuy.map 部分,然后将它分配给变量,然后将它移到 StockQuotes 组件之外。然后我收到错误消息,说 StyleTabledCell 和 StyleTable 行无法从材料 ui 中识别。如何重新排列我的组件以使输入字段不会失去焦点?或者有什么钩子可以用来解决这个问题吗?我尝试了 autofocus()、useRef 和将组件移到外面,但似乎没有任何效果。

import React, { useState, useEffect } 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 = ({ availableFunds, setAvailableFunds }) => {

    const [sharesToBuy, setSharesToBuy] = useState(stockData);

    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>
                {sharesToBuy.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" value ={stock.owned} onChange={event => handleChange(event, index)}></input></StyledTableCell>
                        <StyledTableCell align="right">
                            <ThemeProvider theme={theme}>
                                <Button variant="contained" color="primary" className={classes.margin} 
                                disabled={stock.owned === 0 || !stock.owned}
                                onClick={event => handleClick(event, index)}>
                                    BUY
                                </Button>
                            </ThemeProvider>
                        </StyledTableCell>
                    </StyledTableRow>
                    ))}
                </TableBody>
            </Table>
        </TableContainer>
    )
}


【问题讨论】:

  • 我认为这通常是由于 some 包含输入的组件被重新安装,而不是重新渲染,因此失去焦点。您可以尝试创建一个 running condesandbox 来重现焦点问题吗?
  • 好的,谢谢,这里是沙盒链接--> codesandbox.io/s/gallant-framework-88wc4?file=/src/App.js

标签: javascript reactjs


【解决方案1】:

问题

您正在StockQuotes 组件的渲染函数中定义样式化组件。

函数组件的整个函数体就是渲染函数! 如果在渲染中,withStyles HOC 每次都会创建一个新组件。

解决方案

只需将StyledTableCellStyledTableRow 移出StockQuotes 组件即可。

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 StockQuotes = ({ availableFunds, setAvailableFunds }) => {
  ...

  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>
          {sharesToBuy.map((stock, index) => (
            <StyledTableRow key={stock.name}>
              <StyledTableCell component="th" scope="row">
                {stock.name}
              </StyledTableCell>
              <StyledTableCell align="right">${stock.price}</StyledTableCell>
              <StyledTableCell align="right">
                <input
                  type="number"
                  value={stock.owned}
                  onChange={(event) => handleChange(event, index)}
                ></input>
              </StyledTableCell>
              <StyledTableCell align="right">
                <ThemeProvider theme={theme}>
                  <Button
                    variant="contained"
                    color="primary"
                    className={classes.margin}
                    disabled={stock.owned === 0 || !stock.owned}
                    onClick={(event) => handleClick(event, index)}
                  >
                    BUY
                  </Button>
                </ThemeProvider>
              </StyledTableCell>
            </StyledTableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

【讨论】:

  • 这解决了问题!谢谢!这是我第一次使用材质 ui,不知道 withStyles 每次渲染时都会创建新组件。再次感谢?
  • @JudoboyAlex 太棒了!请接受并支持答案。干杯。
猜你喜欢
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2021-03-31
相关资源
最近更新 更多