【问题标题】:React ref.current inside loop working only on first iterationReact ref.current 内部循环仅在第一次迭代时起作用
【发布时间】:2020-05-28 09:37:57
【问题描述】:

我有一个页面,其中带有标签复选框的文件是从地图呈现的。基本上用户可以选择/取消选择文件。 问题是我想添加可以通过单击按钮选择/取消选择所有文件的功能。 我试图为此使用 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 仅适用于第一项。

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    不要使用 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 })))
    }
    

    【讨论】:

    • 实际上文件是从 props 加载的并且没有字段 isChecked。这也是我什至考虑使用 refs 的主要问题。选中/未选中由检查文件是否在选定数组中并返回在 mui Checkbox 组件中使用的布尔值的函数确定
    • 来自props的就好了,别管useEffect,直接把files prop放到state里。使用 ref 读取复选框的值根本不是反应方式。
    猜你喜欢
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 2023-04-07
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    相关资源
    最近更新 更多