【问题标题】:React JS custom table - handling select dropdown in tableReact JS 自定义表格 - 处理表格中的选择下拉列表
【发布时间】:2020-09-16 10:28:39
【问题描述】:

这个表的一些上下文 - 我想创建一个表,用户可以在表头的下拉列表中选择一个选项并进行比较。所以这个表有两列,每一列代表被选中的数据。

我想要实现的是,当在第一列中选​​择 business 时,如何禁用 business / 防止它在第二列中被选中?因为比较两个相同的没有意义。

还有更好的方法来处理两个选择下拉菜单的 onChange 吗?目前我有两种方法,它们非常相似。我尝试只有一种 onChange 方法,但在选择一个时无法阻止两者都发生变化。

这是我到目前为止所做的:

import React, { useEffect, useState } from "react";
import "./styles.css";

const Table = () => {
  const [plan, setPlan] = useState("business");
  const [planToCompare, setPlanToCompare] = useState("pro");

  const handleChange = (e) => {
    e.preventDefault();
    setPlan(e.target.value);
  };

  const handleChange2 = (e) => {
    e.preventDefault();
    setPlanToCompare(e.target.value);
  };

  const data = [
    {
      business: ["Lorem", "Ipsum", "Dolor sit amet"],
      pro: ["Lorem 1", "Ipsum 2", "Dolor sit amet 3"],
      free: ["Lorem 4", "Ipsum 5", "Dolor sit amet 6"]
    }
  ];

  const renderData = (plan1, plan2) => {
    const arr = data[0][plan1];
    const arr2 = data[0][plan2];

    return arr.map((item, index) => (
      <tr key={`plan_${index + 1}`}>
        <td>{item}</td>
        <td>{arr2[index]}</td>
      </tr>
    ));
  };

  return (
    <div className="container">
      <table>
        <thead>
          <tr>
            <th>
              <select datachosen={plan} onChange={(e) => handleChange(e)}>
                <option value={"business"}>Business</option>
                <option value={"pro"}>Pro</option>
                <option value={"free"}>Free</option>
              </select>
            </th>
            <th>
              <select
                id={"select2"}
                datachosen={planToCompare}
                onChange={(e) => handleChange2(e)}
              >
                <option value={"pro"}>Pro</option>
                <option value={"free"}>Free</option>
                <option value={"business"}>Business</option>
              </select>
            </th>
          </tr>
        </thead>
        <tbody>{renderData(plan, planToCompare)}</tbody>
      </table>
    </div>
  );
};

export default Table;

这是一个有效的codesandbox 以查看完整视图

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您需要将下拉数据保存在变量中,但是当您在 const data = .. 中启动它时,它会在每次渲染组件时重新创建,因此您需要将其保存在 useState 中或使用 @987654322 @

    useState:如果您想更改数据,这很好,例如:添加另一个选项

    const [data, setData] = useState([
      {
        business: ["Lorem", "Ipsum", "Dolor sit amet"],
        pro: ["Lorem 1", "Ipsum 2", "Dolor sit amet 3"],
        free: ["Lorem 4", "Ipsum 5", "Dolor sit amet 6"]
      }
    ]);
    

    useMemo:如果您不愿意更改选项,这很好。

    const data = useMemo(() => {
      return [
        {
          business: ["Lorem", "Ipsum", "Dolor sit amet"],
          pro: ["Lorem 1", "Ipsum 2", "Dolor sit amet 3"],
          free: ["Lorem 4", "Ipsum 5", "Dolor sit amet 6"]
        }
      ];
    }, []);
    

    然后我需要两个变量来保存每个下拉菜单的选项

    // used useMemo because i want to update my planDropDownOptions only if data or planToCompare values gets changed
    const planDropDownOptions = useMemo(() => {
      return Object.keys(data[0]).filter((option) => option !== planToCompare);
    }, [data, planToCompare]);
    
    // used useMemo because i want to update my planToCompareDropDownOptions only if data or plan values gets changed
    const planToCompareDropDownOptions = useMemo(() => {
      return Object.keys(data[0]).filter((option) => option !== plan);
    }, [data, plan]);
    

    现在我们渲染选项时应该是这样的

    <select datachosen={plan} onChange={(e) => handleChange(e)}>
      {planDropDownOptions.map((option) => {
        return (
          <option key={option} value={option}>
            {option}
          </option>
        );
      })}
    </select>
    

    这里是demo

    【讨论】:

    • 非常感谢您的详细解释!它似乎更有效 - 完全错过了 useMemo 用法
    • 很高兴能帮到你
    • 关于数据形状的问题.. 如果我要改变它,所以这个形状 - pastebin.com/uC7UJcyU 在 useMemo 方面访问数据的最佳方式是什么?
    • 检查使用Object.keys(data).filter((option)不是data[0]更改为data
    猜你喜欢
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 2019-09-06
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多