如何在选择选项中使用复选框?反应钩

时间:2020-06-17 07:00:59

标签: javascript reactjs react-hooks

目前,我正在尝试创建此设计。

hoo

它没有按预期打开和关闭。 我还创建了一个codesandbox

三件事:
1.我有一个onClick,但不确定打开和关闭按钮的逻辑是否正确。这里是否应该有useEffect来监听更改?

const showPlatformOptions =()=> {
  //  let checkboxes = el;
  //  console.log("ref:",myRef.current)
  //   if (!expanded) {
  //    //checkboxes.style.display = "block";
  //     setExpanded(true);
  //   } else {
  //   // checkboxes.style.display = "none";
  //     setExpanded(false);
  //   }


  }
  1. 我有一个名为selectionOptions的onChange,它应该让我知道选择了哪个平台,但是目前一次只显示一个平台,为什么?

  2. 还有另一种方法来创建此下拉列表和复选框。也许是使用钩子的库?

感谢您的帮助。

import React, { useState,useEffect, useRef} from "react";


const SearchBar =()=>{
  const [query, setQuery] = useState("");
  const [expanded,setExpanded] = useState(false);
  const [selectionOptions, setSelectionOptions] = useState(["Instagram","LinkedIn","Twitter"]);
  const myRef = useRef(null);

  const showPlatformOptions =()=> {
  //  let checkboxes = el;
  //  console.log("ref:",myRef.current)
  //   if (!expanded) {
  //    //checkboxes.style.display = "block";
  //     setExpanded(true);
  //   } else {
  //   // checkboxes.style.display = "none";
  //     setExpanded(false);
  //   }


  }

  const handleQueryChange = event => {
    console.log("Event:",event.target.value)
    setQuery(event.target.value);
  };

  return (
    <form onSubmit={showPlatformOptions}>
      <div className="w-64">
        <div className="relative" onClick={showPlatformOptions}>
          <h6>PLATFORMS </h6>
          <select className="w-full font-semibold"  onChange={handleQueryChange}>
              {selectionOptions.map((platform,x) => (
                  <option key={x} value={platform}>
                      {platform}
                  </option>
              ))}
          </select>
          <div className="absolute left-0 right-0 top-0 bottom-0"></div>
        </div>
        <div 
        ref={myRef}
        className="checkboxes border-gray-200 border border-solid">
          <label htmlFor="one" className="block ">
            <input type="checkbox" id="one" onChange={handleQueryChange} className="m-3"/>
            Instagram</label>
          <label htmlFor="two" className="block">
            <input type="checkbox" id="two" onChange={handleQueryChange} className="m-3"/>
            LinkedIn</label>
          <label htmlFor="three" className="block">
            <input type="checkbox" id="three" onChange={handleQueryChange} className="m-3"/>
            Twitter</label>
        </div>
      </div>
    </form>
  );
}

3 个答案:

答案 0 :(得分:3)

到目前为止,您的逻辑和代码真的很不错!我会按顺序回答您的问题:

  1. 我有一个onClick,但是我不确定打开和关闭按钮的逻辑是否正确。这里还应该有一个useEffect来监听更改吗?

是的,您可以选择下拉菜单的隐藏和显示逻辑。唯一的事情是您不必在那里担心CSS。您可以使用此布尔值在状态更改时显示或隐藏下拉菜单。

  1. 我有一个名为selectionOptions的onChange,它应该让我知道选择了哪些平台,但是当前一次只显示一个平台,为什么?

很好的问题,其原因是因为它触发了“每个”复选框的更改。更改复选框时,您将看到事件触发,并仅显示新复选框的值。复选框本身就是event.target所指的内容。不是整个表格

  1. 还有另一种方法来创建此下拉列表和复选框。也许图书馆使用钩子?

在这种情况下,我认为您不需要。我带了您的代码沙箱,并通过添加一些额外的代码来对其进行了增强,以显示您的距离!

Here it is

我将指出我所做的一些更改:

  1. 不是使用CSS,而是使用您的expanded变量来确定是否应渲染下拉列表。这个条件逻辑在第50行。

  2. 因为要跟踪所有不同的查询,所以我更改了query变量以跟踪在数组中选择了哪些查询。这样做的逻辑在第26行,但是基本上,如果用户取消选中一个复选框,则会将其从数组中删除(如果有的话),如果他们选中了它,则会将其添加到数组中(如果没有的话)。

希望这对您有所帮助!

答案 1 :(得分:2)

Code Novitiate给出的答案非常适合解决现有代码中的错误good这是简化代码的稍微不同的方法。

当前,您正在尝试渲染select分别渲染复选框。 select及其内容从未真正使用过,从视觉上显示下拉图标也是如此。

我个人觉得原生select标签很难使用,尤其是当您要选择多个选项时。多数精选库似乎都是根据div创建自己的组件并将其样式设置为外观select,我认为这也是最好的方法be

方法

  • 根据下拉列表是否已扩展,有条件地呈现复选框
  • 保持跟踪本地状态的选择
  • 每当单击其中一个复选框时更新状态
  • 下拉标题中的渲染选择
  • 样式下拉标题看起来像一个选择
    • 在我的示例中,我在css中添加了一个三角形,但是您将使用与您的设计更匹配的东西

示例

我整理了this CodePen,希望对您有用

其他建议

  • react-select是一个非常好的库,可以满足您的需求,请看一下Multi示例。
  • 鉴于selectionOptions从未改变,因此没有理由将其保持为状态。您可以只声明一个数组。在我的示例中,这是PLATFORMS常量。
  • 删除<div className="absolute left-0 right-0 top-0 bottom-0" />。看起来效果是创建一个覆盖整个区域的div?这给我带来了麻烦,因为它会干扰某些点击事件?

答案 2 :(得分:1)

您要为每个元素添加一个带复选框的下拉菜单。请参阅Sandbox 了解整个下拉列表的构成。

您使用的方法不是正确且有点复杂且不可重用。作为回应,整个想法是创建通用的可重用组件,但是您的代码与用例紧密相关。创建“选择”然后分别创建复选框列表没有意义。 复选框应该显示为下拉菜单的子项,而不是在其外部,从而使您很容易管理下拉菜单及其状态。