【问题标题】:Separate checkbox for each table row in React.jsReact.js 中每个表格行的单独复选框
【发布时间】:2020-11-28 16:42:10
【问题描述】:

我有一个功能组件,它返回一个包含许多行的表,如下所示:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";

function Table({ data }) {
    const [checked, setChecked] = useState(false);
    const handleChange = (event) => {
        setChecked(event.target.checked);
    };

return (
    // Some table head code
    <TableBody>
        {data.map((row) => (
            <TableRow key={row.id}>
                <TableCell align="left">
                    <Checkbox
                        checked={checked}
                        onChange={handleChange}
                        inputProps={{ "aria-label": "primary checkbox" }}
                    />
                </TableCell>
            </TableRow>
            // More table row code here
        ))}
    </TableBody>
  );
}

每一行都有一个复选框。问题是当我点击一个复选框时,其他行上的所有其他复选框都被选中。我该怎么办。

【问题讨论】:

  • 您的意思是要添加“全选”功能吗?
  • 不,我只想选中我选中的复选框,而不是全部。

标签: javascript reactjs material-ui


【解决方案1】:

出于某种原因,我尝试了这个并且它有效:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";

function Table({ data }) {
const [checked, setChecked] = useState({});
const handleChange = (event, row) => {
    setChecked({ id: row.id, check: event.target.checked });
};

return (
    // Some table head code
    <TableBody>
        {data.map((row) => (
            <TableRow key={row.id}>
                <TableCell align="left">
                    <Checkbox
                        checked={checked}
                        onChange={(e) => handleChange(e, row)}
                        inputProps={{ "aria-label": "primary checkbox" }}
                    />
                </TableCell>
            </TableRow>
        ))}
    </TableBody>
);

}

【讨论】:

    【解决方案2】:

    简单地说,发生这种情况的原因是您将相同的状态传递给每个输入并更改处理函数。如果我们要去掉函数和状态值的引用层,这就是您当前在代码中拥有的内容

    .map => new Map([
    <input
      type="checkbox"
      checked={false}
      onChange={(event) => set(event.target.checked)}
     />,
     <input
      type="checkbox"
      checked={false}
      onChange={(event) => set(event.target.checked)}
     />
     // ... and so on for each and every one of them
    ])
    

    所以如果你选中一个,它会改变所有的

    您需要为每个复选框声明一个单独的状态,或者将它们合并为一个大的复选框简化状态。无需手动声明每个复选框的最简单方法是动态生成它们并将reduce它们设置为单一状态:

    import React, { useState, ChangeEvent } from 'react'
    
    // example of what gets passed
    const data = [
      { id: 0 },
      { id: 1 },
      { id: 2 },
      { id: 3 },
    ]
    
    // Checkbox component
    const Table ({ data }) => {
      // in case 'data' is async you'll need to use useEffect or useCallback
      // generates individual state for each data row
      const initialState = data.reduce(
        (state, current) => (
          Object.assign(state, { [current.id]: false })
        ),
        {}
      ) //  {0: false, 1: false, 2: false, 3: false}
    
      const [checkboxes, setCheckboxes] = useState(initialState)
    }
    

    现在我们已经处理好了我们的状态,我们只需要编写我们的onChange 处理程序。

    const handleToggle = (event: ChangeEvent<HTMLInputElement>) => {
      const { checked, name } = event.target
      setCheckboxes(prevState => ({
        ...prevState,
        [name]: checked,
      }))
    }
    

    并产生您的回报:

    return (
      <div className="App">
        {/* in case your id does not match index, use Object.entries instead */}
        {Object.values(checkboxes).map((isChecked, index) => (
          <TableRow key={index}>
            <TableCell align="left>
              <Checkbox
                name={index}
                checked={isChecked}
                onChange={handleToggle}
              />
            </TableCell>
          </TableRow>
        ))}
      </div>
    );
    

    这是一个有效的代码框示例:

    【讨论】:

      猜你喜欢
      • 2015-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多