首页 > 解决方案 > 文本字段在表格 ReactJs 中无法正常工作

问题描述

我有一个包含对象数组的对象

initialPreconfigTodoState = { 
todos: [
{
  title: 'title1',
  dueDate: new Date(),
  create: true,
  assignedTo: 'role',
},
{
  title: 'title2',
  dueDate: new Date(),
  create: true,
  assignedTo: 'role',
}]
};

我使用这个对象数组来控制表格中文本字段的状态

const [preconfig, setPreconfig] = useState(initialPreconfigTodoState);
 


{preconfig.todos.map((todo, index) => {
                  return (
                    <TableRow
                      className="h-64 cursor-pointer"
                      key={Math.random()}
                    >
                      <TableCell className="th" component="th" scope="row">
                        <TextField
                          id={`titleForm${index}`}
                          name={`titleForm${index}`}
                          onChange={(event) => handleTitle(event, index)}
                          value={todo.title}
                          type="text"
                          variant="outlined"
                          required={todo.create ? true : false}
                          fullWidth
                        />
                      </TableCell>

当我尝试输入文本字段时,我不知道会发生什么,但我需要为我输入的每个字符单击文本字段,我认为是 useState 钩子在重新渲染组件时导致此问题,我不能找到解决方案。

这是我在 onChange 回调上的句柄函数,

const handleTitle = (event, index) => {
let newArray = [...preconfig.todos];
newArray[index] = {
  ...newArray[index],
  title: event.target.value,
};
setPreconfig({ todos: newArray });

};

这是完整的代码

const initialPreconfigTodoState = {
todos: [
{
  title: "title1",
  dueDate: new Date(),
  create: true,
  assignedTo: "Role"
},
{
  title: "title2",
  dueDate: new Date(),
  create: true,
  assignedTo: "Role"
}
]
};
function TodoDialog() {
 const [preconfig, setPreconfig] = 
 useState(initialPreconfigTodoState);

 const handleTitle = (event, index) => {
  let newArray = [...preconfig.todos];
  newArray[index] = {
  ...newArray[index],
  title: event.target.value
 };
 setPreconfig({ todos: newArray });
};

return (
<div>
  <Dialog open={true} maxWidth="xl" scroll="paper">
    <DialogContent>
      <div>
        <Table aria-labelledby="tableTitle">
          <TableBody>
            <TableRow className="h-64 cursor-pointer" key=. 
              {Math.random()}>
              <TableCell className="th" component="th" scope="row">
                Title
              </TableCell>

              <TableCell className="th" component="th" scope="row">
                Due Date
              </TableCell>
              <TableCell className="th" component="th" scope="row">
                Asigned To
              </TableCell>

              <TableCell className="th" component="th" scope="row">
                Create
              </TableCell>
            </TableRow>

            {preconfig.todos.map((todo, index) => {
              return (
                <TableRow
                  className="h-64 cursor-pointer"
                  key={Math.random()}
                >
                  <TableCell className="th" component="th" scope="row">
                    <TextField
                      id={`titleForm${index}`}
                      name={`titleForm${index}`}
                      onChange={(event) => handleTitle(event, index)}
                      value={todo.title}
                      type="text"
                      variant="outlined"
                      required={todo.create ? true : false}
                      fullWidth
                    />
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </div>
    </DialogContent>
    <DialogActions>
      <Button color="primary" variant="contained">
        Cancel
      </Button>
      <Button type="submit" color="primary" variant="contained" autoFocus>
        Save
      </Button>
    </DialogActions>
  </Dialog>
</div>
  );
}
    

标签: reactjsmaterial-uiuse-state

解决方案


那是因为key={Math.random()}在 TableRow 上。

将其更改为key={index},它应该可以工作。

随着Math.random()您的键更改每个渲染和反应失去它的参考。


推荐阅读