反应表格重新渲染,在表格单元格中输入文本时失去焦点

iBl*_*hhz 2 rendering input reactjs

我有一个反应表如下:

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

在此输入图像描述

表.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);
}
Run Code Online (Sandbox Code Playgroud)

这是我的表代码:

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

小智 6

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

创建一个 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}
/>

)
Run Code Online (Sandbox Code Playgroud)

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