【问题标题】:React Checkbox Component returns unique key prop errorReact Checkbox Component返回唯一键道具错误
【发布时间】:2020-07-17 02:16:43
【问题描述】:

我有一个反应复选框可重用组件,它返回唯一键道具错误并在单击任何人时检查值数组中的所有框。

import React, { useState } from 'react'

export default function Checkboxes({name, values}) {
    // handle with dispatch from globalState
    const useCheckbox = () => {
        const [checked, setChecked] = useState(false)

        return {
            checked,
            onChange: e => setChecked(e.target.checked)
        }
    }

    const checkbox = useCheckbox()

    return (
        <>
            {
                values.map((value, key) => (
                    <>
                        <input key={`${name}-${key}`} type="checkbox" value={value} {...checkbox} /> {value}
                    </>
                ))
            }
        </>
    )
}

在应用程序中大量使用它来构建问卷。一个示例用例是

<Checkboxes 
    name="Risk_Response_management"
    values={["Program", "Design", "Procurement(Bid/Cost Estimation)", "Production"]} 
/>

当点击任何呈现的值时,所有复选框都会被选中,而应该只选中一个。在 useCheckbox 声明上方的注释中描述的最后一个用例是使用从 useReducer 挂钩到一个状态的调度,该状态应该在 bug 被压扁后工作,以便给当前用户一些视觉反馈。

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    一方面,我建议只为你的键使用值,它更简单/更干净。而且您不能使用速记片段语法,因为键需要位于返回内容的顶层。

    那么对于所有被选中的复选框,这是因为您只调用一次 useCheckbox 并将其用于所有复选框。而是这样做。

    const Checkbox = () => {
      const [checked, setChecked] = useState(false);
      return (
        <>
          <input
            type="checkbox"
            checked={checked}
            onChange={e => setChecked(e.target.checked)}
          />
          {value}
        </>
      );
    }
    
    export default function Checkboxes({name, values}) {
        // handle with dispatch from globalState
      return (
        <>
          <p>{name}</p>
          {values.map(value => (
            <Checkbox key={value} value={value} />
          ))}
        </>
      );
    

    【讨论】:

      【解决方案2】:

      您收到此错误,因为您在 .map() 中返回了 React Fragment,并且 key 必须位于父元素上。它应该看起来更像这样:

      return values.map((value, key) => (
          <span key={`${name}-${key}`}>
              <input type="checkbox" value={value} {...checkbox} /> {value}
          </span>
      ));
      

      或者,您可以更新创建片段的方式,并使用Keyed Fragments

      【讨论】:

      • 谢谢。了解到key应该放在父组件中
      【解决方案3】:

      查看沙盒的工作示例:

      https://codesandbox.io/s/aged-sound-d1v47?file=/src/Checkboxes.js

      注意事项:

      • 你的状态是在你的处理函数中作用域的,而它应该在你的组件中作用域
      • 状态应该存储选中复选框的值
      • 应根据状态值有条件地检查每个复选框
      • 您不应在键或映射中使用索引迭代,并将片段作为外层
      import React, { useState } from "react";
      
      export default function Checkboxes({ name, values }) {
        const [checked, setChecked] = useState("");
      
        const handleChange = e => {
          setChecked(e.target.value);
        };
        return (
          <>
            {values.map(value => (
              <span key={`${name}-${value}`}>
                <input
                  type="checkbox"
                  value={value}
                  onChange={handleChange}
                  checked={checked === value}
                />{" "}
                {value}
              </span>
            ))}
          </>
        );
      }
      
      

      【讨论】:

      • 嗨,谢谢。然而,我发现这个解决方案给了我一种单选按钮的功能,而这不是当时所需要的
      • 另外,你的代码沙箱坏了,所以我看不到它的实际效果。感谢您的注释,但信息量很大
      猜你喜欢
      • 2019-11-19
      • 2016-07-09
      • 1970-01-01
      • 2022-07-12
      • 2014-03-18
      • 2020-11-20
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多