如何使用usestate钩子避免重复

3htmauhk  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(282)

我正在制作一个表单,它使用许多字段将数据发布到数据库中。我有80多个字段,如“标题、正文html、价格、比较价格、供应商、权重”等。我的代码非常重复,有没有办法缩短代码?我删掉了很多代码,因为它有600多行代码,如果我写了两个单独的函数,那么就太混乱了 handleChangeselectHandler 作为获取下拉列表值的小助手 datalist 要存储到中的输入 state ... 这些值必须存储在不同的状态中,因为我需要每个值执行axios调用,以将其特定字段存储到正确的数据字段中。

import React, { useState } from "react";

function handleChange(e, setter) {
  return setter({ value: e.target.value });
}

function selectHandler(setter) {
  return (
    <>
      <input
        list="headers"
        placeholder="Select one"
        onChange={(e) => handleChange(e, setter)}
      />
      {/* headers comes from mapped api in another file */}
      <datalist id="headers">{headers}</datalist>
    </>
  );
}

function PushToDB() {
  const [showExtraImageInputs, setShowExtraImageInputs] = useState(false);

  const [titleHeader, setTitleHeader] = useState();
  const [handleHeader, setHandleHeader] = useState();
  const [descriptionHtmlHeader, setDescriptionHtmlHeader] = useState();
  const [image1Header, setImage1Header] = useState();
  const [image2Header, setImage2Header] = useState();
  const [altText1, setAltText1] = useState();
  const [altText2, setAltText2] = useState();

  return (
    <>
      <form onSubmit={(e) => e.preventDefault()}>
        // each label uses the helpers to get the dropdown values and store it in state
        <label>Title: {selectHandler(setTitleHeader)}</label>
        <label>Body html: {selectHandler(setDescriptionHtmlHeader)}</label>
        <label>Handle: {selectHandler(setHandleHeader)}</label>
        <label>Image: {selectHandler(setImage1Header)}</label>
        <label>Img alt text: {selectHandler(setAltText1)}</label>
        {/* ADD MORE IMAGES */}
        {showExtraImageInputs && (
          <>
            <div>Image 2: {selectHandler(setImage2Header)}</div>
            <div>Img alt text 2: {selectHandler(setAltText2)}</div>
          </>
        )}
      </form>
    </>
  );
}
export default PushToDB;

这就是axios数据的外观。正如您所看到的,我需要来自state的每个值。同样,它有80多个字段。

useEffect(() => {
  if (pushState && apiData) {
    let productValues = apiData.data.data;
    productValues.map((e) => {
      let url = `url`;
      return axios
        .get(url)
        .then((res) => {
          if (res) {
            // if the data is already in db, do not push
            if (res.data.products.length === 0)
            // if there is no data then push data
              return setProductData({
                variables: {
                  // values from state
                  title: e[titleHeader?.value],
                  descriptionHtml: e[descriptionHtmlHeader?.value],
                  handle: e[handleHeader?.value],
                  img1: e[image1Header?.value] ?? "",
                  alt1: e[altText1?.value],
                  img2 : e[image2Header?.value] ?? '',
                  alt2: e[altText2?.value], 
                  img3: e[image3Header?.value] ?? '',
                  // and so on
                },
              });
          }
          // this is the logger of whats being pushed into the database
        })
        .then((res) => {
          if (res)
            return axios.post("http://localhost:4000/api/v1/Extradb", {
              data: {
                title: res?.data?.productCreate?.product?.title,
                handle: res?.data?.productCreate?.product?.handle,
                item_id: res?.data?.productCreate?.product?.id,
              },
            });
        });
    });
  }
}, []);
fnx2tebb

fnx2tebb1#

拿出了一个解决方案。。。我只需要做一个物体

function App() {
  const [userInputs, setUserInputs] = useState({})

  function handleChange(e) {
    const { value, name } = e.target
    setUserInputs(prevState => ({
      ...prevState,
      [name]: value
    }))
  }

  function handleInputNaming(name) {
    let capitilizedWord = name.charAt(0).toUpperCase() + name.slice(1);
    return (<input placeholder={capitilizedWord} name={name} value={userInputs[name]} onChange={handleChange} />)
  }

  return (
    <div className="App">
      {handleInputNaming('title')}
      {handleInputNaming('handle')}
      {handleInputNaming('image')}
    </div>
  );
}

export default App;

相关问题