首页 > 解决方案 > React,单击复选框后如何获取数据?

问题描述

我有两个 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;

非常感谢!

标签: javascriptreactjsapiexpress

解决方案


因此,作为摘要,您有一​​个要呈现的列表,并且您想要选择将发送到后端的项目。在这种情况下,您可以使用 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>
    </>
  );
};

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


推荐阅读