【问题标题】:Trying to filter an array using checkboxes and useState, checkbox doesn't stay checked尝试使用复选框和 useState 过滤数组,复选框不会保持选中状态
【发布时间】:2021-12-18 04:31:46
【问题描述】:

我有一个数组,称为reportsData,然后我需要对其进行过滤,生成一些复选框,每个复选框都有一个基于来自另一个数组(emittersData)的每个名称的标签,所以基本上我这样设置它:

const [searchUser, setSearchUser] = useState<string[]>([])

const mappedAndFiltered = reportsData
  .filter((value: any) =>
    searchUser.length > 0 ? searchUser.includes(value.user.name) : true
  )

然后我像这样渲染我的复选框:

function EmittersCheckboxes () {
    const [checkedState, setCheckedState] = useState(
      new Array(emittersData.length).fill(false)
    )

    const handleOnChange = (position: any, label: any) => {
      const updatedCheckedState = checkedState.map((item, index) =>
        index === position ? !item : item
      )

      setSearchUser((prev) =>
        prev.some((item) => item === label)
        ? prev.filter((item) => item !== label)
        : [...prev, label]
      ) 
      setCheckedState(updatedCheckedState)
    };

    return (
      <div className="App">
        {emittersData.map((value: any, index: any) => {
          return (
            <li key={index}>
              <div className="toppings-list-item">
                <div className="left-section">
                  <input
                    className="h-4 w-4 focus:bg-indigo border-2 border-gray-300 rounded"
                    type="checkbox"
                    id={`custom-checkbox-${index}`}
                    name={value.Attributes[2].Value}
                    value={value.Attributes[2].Value}
                    checked={checkedState[index]}
                    onChange={() => handleOnChange(index, value.Attributes[2].Value)}
                    />
                  <label className="ml-3 font-medium text-sm text-gray-700 dark:text-primary" htmlFor={`custom-checkbox-${index}`}>{value.Attributes[2].Value}</label>
                </div>
              </div>
            </li>
          );
        })}
      </div> 
    )
  }

在反应组件上,我正在渲染每个复选框,即li,例如:

<ul><EmittersCheckboxes /></ul>

最后我渲染了mappedAndFiltered

然后没关系,当我单击每个生成的复选框时,它会过滤设置setSearch用户状态的数组并过滤数组。

您可以在此处查看:可流式传输。 com /v6bpk6 看到过滤器正在工作,数组中的项目总数根据选中的复选框(一个或多个)而变化。

但问题是每个复选框都没有被“选中”,它保持空白(未切换)。

我做错了什么,为什么它不检查自己?

【问题讨论】:

  • 这是真实的代码还是你使用 React 组件来渲染每个项目?
  • 我只是把各个函数放了起来,这样容易阅读,因为整个文件很大。如果您需要查看,请在此处查看:pastebin.com/5akZa2X4(代码中有很多未使用的内容,请忽略它们,专注于我在帖子中所说的内容)
  • 你在你的父组件中定义了一个新的EmittersCheckboxes 组件......它会工作,但有点奇怪
  • 我不明白,不明白你想说什么。而且它不起作用..复选框没有保持选中状态。

标签: javascript reactjs typescript checkbox filter


【解决方案1】:

您已经在另一个组件中定义了 EmittersCheckboxes 组件。并且每次父组件渲染(通过状态更改)时,您的内部组件都会被重新定义,一次又一次地导致它失去 React 为您保存的内部状态。

这是一个简化的例子:

import React, { useState } from "react";

function CheckboxeComponent() {
  const [checkedState, setCheckedState] = useState(false);

  return (
    <div>
      <span>CheckboxeComponent</span>
      <input
        type="checkbox"
        checked={checkedState}
        onChange={() => setCheckedState((x) => !x)}
      />
    </div>
  );
}

export default function App() {
  const [counter, setCounter] = useState(1);

  function InternalCheckboxeComponent() {
    const [checkedState, setCheckedState] = useState(false);

    return (
      <div>
        <span>InternalCheckboxeComponent</span>
        <input
          type="checkbox"
          checked={checkedState}
          onChange={() => setCheckedState((x) => !x)}
        />
      </div>
    );
  }

  return (
    <>
      <InternalCheckboxeComponent />
      <CheckboxeComponent />
      <button onClick={() => setCounter((c) => c + 1)}>{counter}</button>
    </>
  );
}

App(父组件)有自己的状态(counter),有一个按钮可以改变这个状态,点击这个按钮会增加计数器,导致App重新渲染。每次渲染都会重新定义一个名为 InternalCheckboxeComponent 的新组件。

InternalCheckboxeComponent 也有一个内部状态 (checkedState)。

还有一个外部定义的函数组件,名为CheckboxeComponent,这个组件 React 能够保持自己的状态,因为它没有被重新定义(它是同一个函数)

如果将每个的状态设置为“选中”并单击按钮,这将导致 App 的重新渲染,这将重新定义 InternalCheckboxeComponent 函数,导致 React 失去其状态。并且CheckboxeComponent 状态保持在 React 中,因为它是相同的功能。

【讨论】:

  • 我理解这一点,我很欣赏你的努力,但这对我在我的问题中展示的目的不起作用。像你一样拥有一个简单的计数器......是的,它有效。但是我尝试像您一样将我的组件隔离在默认功能之外,并且它的工作方式相同(过滤器有效,但复选框没有保持选中状态)。你能帮我修复我的组件吗?
  • 另外,我需要在许多函数中维护我的emittersData。如果我在我的默认函数之外设置发射器数据、setEmittersData,我无法通过许多函数访问它。
  • 将您的emittersData 保存在父组件上,并提供将其操作到子组件的函数。不提供对象本身,在子组件中手动更改不会触发状态更改
猜你喜欢
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 2016-06-19
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多