【问题标题】:React table re-renders, losing focus when input text in table cellReact 表格​​重新渲染,在表格单元格中输入文本时失去焦点
【发布时间】:2021-03-19 22:16:30
【问题描述】:

我有一个反应表如下:

我在下面显示的每个选项卡(EN、CN、VN、TH)中都有一个表格。目前,当我尝试在“消息”列(下表中的第 3 列)中输入文本时,每次输入字母表时都会重新呈现表格。光标将失去焦点,我必须再次手动单击输入框才能继续输入。

table.js

const [playerNotification, setPlayerNotification] = React.useState([
       {
            'language': 'vn',
            'notificationDetails': [
                {
                    'key': 'event',
                    'description': 'test event',
                    'message': ''
                },
                {
                    'key': 'event 2',
                    'description': 'test event 2',
                    'message': ''
                },
                {
                    'key': 'event 3',
                    'description': 'test event 3',
                    'message': ''
                }
            ]
        },
        {
            'language': 'cn',
            'notificationDetails': [
                {
                    'key': 'event',
                    'description': 'test event',
                    'message': ''
                },
                {
                    'key': 'event 2',
                    'description': 'test event 2',
                    'message': ''
                },
                {
                    'key': 'event 3',
                    'description': 'test event 3',
                    'message': ''
                }
            ]
        }];

const updateMessage = (e, value, index, notificationDetailsIndex) => {

        let copyData =  playerNotification.slice();
        let copy = copyData[index];
        let copyDetails = copy.notificationDetails[notificationDetailsIndex];
        copyDetails.message = value;

        copy.notificationDetails[notificationDetailsIndex] = copyDetails;
        copyData[index] = copy;
        
        setPlayerNotification(copyData);
}

这是我的表格代码:

<div className={classes.tabsRoot}>
      <AppBar position="static" color="default">
        <Tabs
          value={value}
          onChange={handleChange}
          indicatorColor="primary"
          textColor="primary"
          variant="scrollable"
          scrollButtons="auto"
          aria-label="scrollable auto tabs example"
        >
          <Tab label="EN" {...a11yProps(0)} />
          <Tab label="CN" {...a11yProps(1)} />
          <Tab label="VN" {...a11yProps(2)} />
          <Tab label="TH" {...a11yProps(3)} />
        </Tabs>
      </AppBar>
      {playerNotification.map((p, index) => {
        return (
          <TabPanel value={value} index={index}>
            <Table key={index} aria-label="simple table">
              <TableHead style={customColumnStyle} className={classes.header}>
                <TableRow key={"header" + p.language}>
                  <TableCell className={classes.customBorderRightStyle}>
                    Event Trigger Key
                  </TableCell>
                  <TableCell className={classes.customBorderRightStyle}>
                    Description
                  </TableCell>
                  <TableCell className={classes.customBorderRightStyle}>
                    Messages
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody style={customColumnStyle}>
                {p.notificationDetails.map((notification, notificationIndex) => {
                  return (
                    <Fragment>
                      <TableRow key={p.language + notificationIndex}>
                        <TableCell
                          style={{ backgroundColor: "rgba(0, 0, 0, 0.05)" }}
                        >
                          {notification.key}
                        </TableCell>
                        <TableCell
                          style={{ backgroundColor: "rgba(0, 0, 0, 0.05)" }}
                        >
                          {notification.description}
                        </TableCell>
                        <TableCell>
                          <input
                            type="text"
                            key={p.language + notification.key + notificationIndex}
                            className={classes.customInputStyle}
                            onChange={(e) =>
                              updateMessage(
                                e,
                                e.target.value,
                                index,
                                notificationIndex
                              )
                            }
                            value={notification.message}
                          />
                        </TableCell>
                        {/* <TableCell>{messageComponent(index, notificationIndex, notification)}</TableCell> */}
                      </TableRow>
                    </Fragment>
                  );
                })}
              </TableBody>
            </Table>
          </TabPanel>
        );
      })}
    </div>

我尝试为每个表格行添加一个唯一键,但行为保持不变 - 我的光标不断失去焦点。当我输入字母时,添加自动对焦会使光标跳到第三行。这是我尝试过的链接 React.js - input losing focus when rerendering.

我认为可能的原因可能是因为我每次输入字母时都在循环表格?非常感谢您帮助指出我的表格代码中的问题以及如何解决它。谢谢!

【问题讨论】:

  • 我遇到了类似的问题。你有想过这个吗?
  • 我们更改了设计并改为固定在一张桌子上:P 所以这个问题尚未解决,但如果您设法找到答案,请告诉我谢谢!
  • 我也更改了我的设计,并将 onChange 状态保留在单元格本身中(类似于文档中的示例)。我不相信有一个解决方案可以按照我们最初的计划去做。

标签: reactjs input rendering


【解决方案1】:

只要您对每个可以修改的单元格都有一个唯一的密钥,我就有一个解决方案。

创建一个 useState 变量或 useRef(理想情况下)变量来保存您要保持焦点的单元格的当前键。然后将此变量修改为当前单元格的键以关注 onChange 函数。然后,如果当前单元格键与焦点变量引用匹配,您将有条件地使用 autoFocus 属性:

let editableKeyToFocus = useRef(null);
const key = getUniqueKey();

return (
<TextField
   key={key}
   onChange={(e) => {
     editableKeyToFocus.current = key;
     onChangeFunctionToCall()
   }
   autoFocus={key === editableKeyToFocus.current}
/>

)

换句话说,您将在每次调用 onChange 时手动保留对要保持焦点的单元格的引用。

【讨论】:

    猜你喜欢
    • 2014-04-29
    • 2018-12-12
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2021-04-18
    相关资源
    最近更新 更多