【问题标题】:using map in collapsible table reactjs在可折叠表reactjs中使用地图
【发布时间】:2020-12-07 22:08:26
【问题描述】:

我有一个看起来像this 的折叠桌。但是,当我单击一行时,两行都会展开。

这是我的代码的样子:

const Transaction = ({ categories }) => {
 const [open, setOpen] = useState(false);

let categoryList = categories.map((category, index) => {
    return (
        <TableRow key={index}>
          <TableCell>
            <IconButton size="small" onClick={() => setOpen(!open)}>
              {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
            </IconButton>
          </TableCell>
          <TableCell component="th" scope="row">
            {category}
          </TableCell>
          <TableCell />
          <TableCell />
          <TableCell />
          <TableCell />
        </TableRow>
      );
  });

 return (
    <div className={classes.root}>
      <Grid container spacing={2}>
        <Grid item xs={12}>
          <TableContainer component={Paper}>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell />
                  <TableCell>Category</TableCell>
                  <TableCell />
                  <TableCell />
                  <TableCell />
                  <TableCell />
                </TableRow>
              </TableHead>
              <TableBody>
                {categoryList}
              </TableBody>
            </Table>
          </TableContainer>
        </Grid>
      </Grid>
    </div>
  );
};

在我的 categoryList 中,我使用 index 作为键,但它仍然扩展两行而不是选定的特定行。我怎样才能只展开一行?

【问题讨论】:

    标签: reactjs loops dictionary indexing key


    【解决方案1】:

    您的表格行需要控制自己的open 状态。目前,您构建代码的方式它们都共享相同的状态并单击任一表行将引用相同的处理程序,该处理程序会更改open 状态,这就是为什么您的两个表行都同时打开和关闭的原因。

    因此,这个解决方案不是让open 保存一个布尔值,而是让它保存一个布尔值数组,最初都设置为 false。

        const [open, setOpen] = useState(categories.map(() => false));
    

    这将创建一个大小为categories 的布尔数组。

    另外,OnClick 函数自然要稍作改动:

    onClick={() => {
      setOpen((pOpen) => pOpen.map((o, i) => {
        if (i === index) return !o;
        return o;
      }));
    }}
    

    现在您可以使用索引open[index] 来了解打开的内容。

    {open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
    

    完整的sn-p如下:

    const Transaction = ({ categories }) => {
     /* 
      * Change this [Origninal]:
      * const [open, setOpen] = useState(false);
      * To this:
      */
     const [open, setOpen] = useState(categories.map(() => false));
    
    
      React.useEffect(() => {
        if (categories.length !== open.length) {
          setOpen(categories.map(() => false));
        }
      }, [categories, open]);
    
    
    let categoryList = categories.map((category, index) => {
        return (
            <TableRow key={index}>
              <TableCell>
                <IconButton size="small" 
                            onClick={() => {
                              setOpen((pOpen) => pOpen.map((o, i) => {
                                if (i === index) return !o;
                                return o;
                              }));
                            }}
                  {open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
                </IconButton>
              </TableCell>
              <TableCell component="th" scope="row">
                {category}
              </TableCell>
              <TableCell />
              <TableCell />
              <TableCell />
              <TableCell />
            </TableRow>
          );
      });
    
     return (
        <div className={classes.root}>
          <Grid container spacing={2}>
            <Grid item xs={12}>
              <TableContainer component={Paper}>
                <Table>
                  <TableHead>
                    <TableRow>
                      <TableCell />
                      <TableCell>Category</TableCell>
                      <TableCell />
                      <TableCell />
                      <TableCell />
                      <TableCell />
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {categoryList}
                  </TableBody>
                </Table>
              </TableContainer>
            </Grid>
          </Grid>
        </div>
      );
    };
    

    【讨论】:

    • 我收到警告:列表中的每个孩子都应该有一个唯一的“关键”道具。如何向 pOpen.map 添加密钥?
    猜你喜欢
    • 2022-11-19
    • 1970-01-01
    • 2022-01-06
    • 2018-07-05
    • 2017-03-30
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    相关资源
    最近更新 更多