【问题标题】:React, how to get data after clicking on checkbox?React,单击复选框后如何获取数据?
【发布时间】:2020-10-19 11:48:04
【问题描述】:

我有两个 React 组件:ul 列表和每个 li 项目,这是一个闪存卡。在每个项目中都有两个字符串:搜索词及其翻译(api.source、api.target)以及复选框。单击复选框并稍后单击按钮(CardList.js)后,我想获取我的数据并将其发送到我的后端。谁能告诉我如何获取这两个字符串并将它们传递给 addFlashCards 函数?现在我已将其硬编码为 dataSet

const CardsList = ({ fetchedApi }) => {
  const addFlashCards = () => {
    const dataSet = [
      {
        apiSource: "sampleDataCheckbox",
        apiTarget: "sampleDataCheckbox2",
      },
      {
        apiSource: "sampleDataCheckbox",
        apiTarget: "sampleDataCheckbox",
      },
    ];

    const url = "/api/saveToDB";
    axios
      .post(url, { data: dataSet, user: "SOME USER" })
      .then((res) => {
        const fetchedData = res.data;
        console.log(fetchedData);
      })
      .catch((err) => console.error(err));
  };

  return (
    <div className="cards-list">
      <button onClick={addFlashCards}>Add</button>
      <ul className="cards-list__list">
        {fetchedApi.map((api) => {
          return <CardItem api={api} />;
        })}
      </ul>
    </div>
  );
};

export default CardsList;
const CardItem = ({ api }) => {
  const [isChosenCard, setIsChosenCard] = useState(false);

  const clickedCheckbox = () => {
    setIsChosenCard(!isChosenCard);
  };

  return (
    <>
      <li className="card-item">
        <input
          className="fiszkiBox"
          type="checkbox"
          onClick={clickedCheckbox}
        />

        <div className="flip-card">
          <div className="flip-card-inner">
            <div className="flip-card-front">
              <p id="api-source">{api.source}</p>
            </div>
            <div className="flip-card-back">
              <p className="api-target">{api.target}</p>
            </div>
          </div>
        </div>
      </li>
    </>
  );
};

export default CardItem;

非常感谢!

【问题讨论】:

  • 如果可能的话,使用一些硬编码数据创建此场景的 jsfiddle 工作链接并在此处共享该链接

标签: javascript reactjs api express


【解决方案1】:

因此,作为摘要,您有一​​个要呈现的列表,并且您想要选择将发送到后端的项目。在这种情况下,您可以使用 useState 钩子向 CardList 添加一个空数组,该钩子将包含所选项目。

const CardsList = ({ fetchedApi }) => {
  const [selectedItems, setSelectedItems] = useState([]);
  const addFlashCards = () => {
    // Here you can do some kind of check with mapping the selectedItems Array, as you need

    const url = "/api/saveToDB";
    axios
      .post(url, { data: selectedItems, user: "SOME USER" })
      .then((res) => {
        const fetchedData = res.data;
        console.log(fetchedData);
      })
      .catch((err) => console.error(err));
  };

  function selectItem(item){
    // So below, we do it to make component render by creating new array instead of mutating the current array. Actually try to play with code, you can even remove these and mutate current and set.
    let selectedItemsArray = [...selectedItems];

    // Here below, we check if selectedItem already exists in selectedItemsArray, if it exists we would like to remove it right? if it does not exist, we just add it to array by pushing it.
    let itemCheck = selectedItemsArray.find((arrayItem) => arrayItem.source === item.source);

    if (itemCheck) {
        // Here if selected item was in array, we just remove it by filtering the array
        selectedItemsArray = selectedItemsArray.filter((arrayItem) => arrayItem.source !== item.source)
    }
    else{
        // Here selected item was not in our array so we just push it
        selectedItemsArray.push(item)
    }
    setSelectedItems(selectedItemsArray);
  }

  return (
    <div className="cards-list">
      <button onClick={addFlashCards}>Add</button>
      <ul className="cards-list__list">
        {fetchedApi.map((api, index) => {
          return <CardItem api={api} onItemSelected={item=> selectItem(item)} />;
        })}
      </ul>
    </div>
  );
};

const CardItem = ({ api, onItemSelected }) => {   
  return (
    <>
      <li className="card-item">
        <input
          className="fiszkiBox"
          type="checkbox"
          onClick={() => onItemSelected({
              source: api.source,
              target: api.target
          })}
        />

        <div className="flip-card">
          <div className="flip-card-inner">
            <div className="flip-card-front">
              <p id="api-source">{api.source}</p>
            </div>
            <div className="flip-card-back">
              <p className="api-target">{api.target}</p>
            </div>
          </div>
        </div>
      </li>
    </>
  );
};

这些代码应该可以工作,希望你也明白逻辑。这种方法在您的情况下是合乎逻辑的。

【讨论】:

  • 感谢您的帮助。我没有具体解释我想做什么。从项目中选择复选框后,用户必须单击按钮来证明该选择。 。而不是硬编码的数据集,我想从项目中获得一个值 t(api.source, api.target),用户通过单击复选框来选择(每个项目都有复选框、api.source、api.target)
  • 好吧,让我随意编辑吧,实际上几乎一样。
  • 好的,编辑,现在检查它应该是你需要的。如果有错误等,不要忘记通过记录检查代码。
  • 你能写一些cmets到selectItem函数吗?我不明白那里到底有什么。非常感谢:)
  • 好的添加了一些cmets,我的建议是添加console.log到每一步并检查数据。然后您将能够更好地理解流程。
猜你喜欢
  • 1970-01-01
  • 2017-06-27
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
相关资源
最近更新 更多