首页 > 解决方案 > React ref.current 内部循环仅在第一次迭代时起作用

问题描述

我有一个页面,其中从地图呈现带有标签复选框的文件。基本上用户可以选择/取消选择文件。问题是我想添加可以通过单击按钮选择/取消选择所有文件的功能。我试图为此使用 refs。

 const fileRef = React.useRef([]);

然后我有简单的地图:

files.map((file, index) => 
    <FormControlLabel 
        ref={el => fileRef.current[index] = el}
        control={...}
        label={file.name}
    />
)

我试图创建这样的功能:

const selectAll = () => {
    for(let i = 0; i < files.length; i++) {
        fileRef.current[i].control.click();
    }
}

问题是只有第一个文件被选中/取消选中。选定的文件保存在数组中。手动单击是通过简单的 handleChange 处理的,我在其中选择带有 event.target.value 的复选框,而在取消选择时我只使用 array.filter。

例如,如果我用两个不同的索引制作两个按钮,那么它可以工作,但在循环内索引似乎没有生效。

有没有办法一键选择/取消选择所有文件?我认为取消选择很容易,我只是清除数组,但选择似乎是个问题。Ref 仅适用于第一项。

标签: reactjsreact-hooks

解决方案


不要使用 ref 尝试单击所有复选框,只需更改文件状态以检查所有文件。

我假设它files是由一些 api 调用加载的,并且您的组件正在执行类似的操作

const [files, setFiles] = useState([])

useEffect(() => {
  loadFiles().then(files => {
    const filesWithCheckParam = files.map(file => ({ ...file, isChecked: false }))
    setFiles(filesWithCheckParam)
  })
}, [])

现在您可以放入一个按钮或另一个复选框或任何带有更改文件状态的单击处理程序的内容,例如

const handleCheckAllClick = checked => {
  setFiles(fs => fs.map(f => ({ ...f, isChecked: checked })))
}

推荐阅读