我正在try 构建一个多复选框,并使用usasta函数将选中的值推入array.但是,当我选中一个复选框时,只有当我选中其他选项时,它的值才会被推送到array.

对于EX:

  1. 如果选中红色选项,则不会将任何内容推送到array.
  2. 如果我选中蓝色选项,则只有红色值(之前选中)被推送到array.
  3. 如果选中绿色选项,则红色和蓝色值仅出现在数组中

以下是我的代码

import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { filterProducts } from "../../redux/Shopping/shopping-actions";

const filterValues = [
  {
    heading: "Colour",
    items: ["Red", "Blue", "Green"],
  },
  {
    heading: "Gender",
    items: ["Men", "Women"],
  },
  {
    heading: "Price",
    items: ["0-Rs250", "Rs251-450", "Rs 450"],
  },
  {
    heading: "Type",
    items: ["Polo", "Hoodie", "Classic"],
  },
];

const Filter = ({ filter, searchArray, setSearchArray }) => {
  
  const handleCheck = (e) => {
    if (e.target.checked === true) {
      setSearchArray([...searchArray, e.target.value]);
    } else {
      setSearchArray(searchArray.filter((id) => id !== e.target.value));
    }
    if (searchArray.length > 0) {
      filter(searchArray);
    }
  };
  return (
    <div>
      <aside className="ml-4 mt-16">
        {filterValues.map((item) => {
          return (
            <>
              <h3 className="mb-4 mt-2 ml-4 font-semibold text-gray-900 dark:text-black">
                {item.heading}
              </h3>

              <ul className="w-48 text-sm font-medium text-black-900 bg-white dark:text-white">
                {item.items.map((i) => {
                  return (
                    <li className="w-full rounded-t-lg">
                      <div className="flex items-center pl-3">
                        <input
                          id="checkbox"
                          type="checkbox"
                          value={i}
                          onChange={(e) => handleCheck(e)}
                          className="w-4 h-4 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
                        />
                        <label
                          for="checkbox"
                          className="py-3 ml-2 w-full text-sm font-medium text-gray-900 dark:text-black"
                        >
                          {i}
                        </label>
                      </div>
                    </li>
                  );
                })}
              </ul>
            </>
          );
        })}
      </aside>
    </div>
  );
};

const mapDispatchToProps = (dispatch) => {
  return {
    filter: (query) => dispatch(filterProducts(query)),
  };
};

export default connect(null, mapDispatchToProps)(Filter);

过滤函数

case actionTypes.FILTER_PRODUCT:
      const searchParameters = data && Object.keys(Object.assign({}, ...data));
      let filterData;
      console.log("testing", action.payload);

      if (action.payload.length === 0) {
        filterData = state.products;
      } else {
        action.payload.forEach((i) => {
          filterData = state.products.filter((item) =>
            searchParameters.some((parameter) =>
              item[parameter]
                .toString()
                .toLowerCase()
                .includes(i.toLowerCase())
            )
          );
        });
      }
      return {
        ...state,
        filteredData: filterData,
      };
    default:
      return state;
  }

推荐答案

当您调用setSearchArray来更新状态时,更新的值在下一行代码中不会立即可用. 因此,当您选中第一个复选框时,更新后的状态仍然不可用,searchArray的长度仍然为零.这就是没有将第一个复选框值添加到数组的原因.

要解决此问题,可以将函数传递给setSearchArray,而不是新值.此函数将接收前一状态作为参数,并应基于前一状态返回新状态.这就是确保始终基于最新值更新状态的方法.

const Filter = ({ filter }) => {
  const [searchArray, setSearchArray] = useState([]);

  useEffect(() => {
    if (searchArray.length > 0) {
      filter(searchArray);
    }
  }, [searchArray]);

  const handleCheck = (e) => {
    if (e.target.checked === true) {
      setSearchArray([...searchArray, e.target.value]);
    } else {
      setSearchArray(searchArray.filter((id) => id !== e.target.value));
    }
  };

  return (
    <div>
      {filterValues.map((item) => {
        return (
          <div key={item.heading}>
            <h3>{item.heading}</h3>
            <ul>
              {item.items.map((i) => {
                return (
                  <li key={i}>
                    <label>
                      <input
                        type="checkbox"
                        value={i}
                        checked={searchArray.includes(i)}
                        onChange={(e) => handleCheck(e)}
                      />
                      {i}
                    </label>
                  </li>
                );
              })}
            </ul>
          </div>
        );
      })}
    </div>
  );
};

useEffect钩子用于在任何时候更新搜索数组状态时调用筛选器函数.与以前一样,使用setSearchArray函数更新searchArray状态.handleCheck函数还被更新为直接使用searchArray状态,并在添加或删除该值之前判断该值是否已存在于数组中.

Reactjs相关问答推荐

当我在React中使用类方法更新模型的状态时,它在严格模式下触发两次

基本react 应用程序正在触发两次Use Effect

.populate() 方法在 mongodb 中不起作用

在 Next13 中将 props 传递给 onClick 从服务器到客户端组件

React useContext 的未定义返回值

FabricJS反序列化问题

在React Router 6中,在路由渲染后更新路由数据

useRef.current.value 为空值

如何根据用户在react.js中的 Select , Select 多个心形图标?

为什么 createSlice 中的 reducer 不能以不同的方式改变状态?

如何测试使用 React.createportal 呈现的组件?

使用 toast 时挂钩调用无效

React 测试库 - 如何断言异步函数之间的中间状态?

无法在 KeyDown 上调用 useCallback 函数

从 API 中提取映射数组后出现重复元素

交换键仍然引入了 fresh 的 DOM 元素

如何实现两个 SVG 形状相互叠加的 XOR 操作?

服务器端分页未按预期工作

bootstrap 导航栏切换器在 reactjs 中不起作用

错误未捕获的错误:[App] 不是 组件. 的所有子组件必须是