#javascript #reactjs #react-hooks
Вопрос:
Я создаю форму, в которой используется множество полей для размещения данных в базе данных. У меня более 80 полей, таких как «заголовок, HTML-код тела, цена, сравнение цен, поставщик, вес» и т. Д. И мой код очень повторяющийся, есть ли способ сделать мой код короче? Я сбрил большую часть своего кода, потому что в нем более 600 строк кода, и было бы слишком сложно опубликовать все целиком, я сделал 2 отдельные функции handleChange
и selectHandler
в качестве небольших помощников, чтобы получить значение раскрывающихся 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 amp;amp; (
<>
<div>Image 2: {selectHandler(setImage2Header)}</div>
<div>Img alt text 2: {selectHandler(setAltText2)}</div>
</>
)}
</form>
</>
);
}
export default PushToDB;
вот как выглядят данные axios. как вы можете видеть, мне нужно каждое значение из штата. и опять же, это более 80 полей.
useEffect(() => {
if (pushState amp;amp; 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,
},
});
});
});
}
}, []);
Ответ №1:
пришло решение… Мне просто нужно было сделать объект
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;