i am using react.i have 2 inputs that by clicking a button dynamically ganerats. this the code:
useEffect(() => {
const myFields = fieldsArray.map((field) => {
return (
<div key={field} className="col-12 m-auto d-flex">
<input id={field} name={`question${field}`} onChange={handleChangeFields} placeholder='سوال' className="form-control col-4 m-2" />
<input id={field} name={`answer${field}`} onChange={handleChangeFields} placeholder='جواب' className="form-control col-4 m-2" />
</div>
)
})
setFields(myFields)
}, [fieldsArray])
i need to save value of 2 inputs together in an opjects like this :
[{question : '',answer : ''}]
and the new 2 input's value are going to update the above array like this:
[{question : '',answer : ''}, {question : '',answer : ''}]
i can save each input's value separately like this :
const handleChangeFields = (e) => {
const { name, value } = e.target
setFieldsValue([...fieldsValue, { [name]: value }])
}
but i want each 2 input's value together i need to save each 2 inputs together. how do i do that?
This is a general example of how I think you can tie in what you're currently doing, and add in as little new code as possible. This logs the new data state when the button is clicked.
Have two states. One for collecting the updated form information (form), and another for the combined form data array (data).
Have a form with a single onChange listener (event delegation) so you can catch events from all the inputs as they bubble up the DOM. That listener calls the handleChange function which updates the form state.
Have a button with an onClick listener that calls handleClick which takes the current form state and adds it to the data state.
I would be a bit wary of storing JSX in state. You should have that map in the component return and only updating the actual field data with basic information.
One final issue - your inputs cannot have the same id. ids must be unique. I'd get rid of them altogether.
const { useEffect, useState } = React;
function Example() {
// Initialise two states. `data` is an array
// and `form` is an object
const [ data, setData ] = useState([]);
const [ form, setForm ] = useState({});
// Add the form data to the `data` array
function handleClick() {
setData([ ...data, form ]);
}
// We're using event delegation so we need to
// check what element we changed/clicked on
// - in this case the INPUT element. We can then
// update the form state with the name/value pair of that input
function handleChange(e) {
const { nodeName, name, value } = e.target;
if (nodeName === 'INPUT') {
setForm({ ...form, [name]: value });
}
}
// Just logs the data state after a change
useEffect(() => console.log(data), [data]);
return (
<form onChange={handleChange}>
<input name="question" type="text" />
<input name="answer" type="text" />
<button
type="button"
onClick={handleClick}
>Update form
</button>
</form>
);
};
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
this problem solved for me :
function App() {
const [results, setResults] = useState([{ question: "", answer: "" }])
// handle input change
const handleInputChange = (e, index) => {
const { name, value } = e.target
const list = [...results]
list[index][name] = value
setResults(list)
}
// handle click event of the Remove button
const handleRemoveClick = (index) => {
const list = [...results]
list.splice(index, 1)
setResults(list)
}
// handle click event of the Add button
const handleAddClick = () => {
setResults([...results, { question: "", answer: "" }])
}
// handle submit to servers
const handlesubmit = () => {
// axios
console.log(results)
}
return (
<div className="App">
{results?.map((result, index) => {
return (
<div key={index}>
<input
name="question"
value={result.question}
onChange={(e) => handleInputChange(e, index)}
/>
<input
name="answer"
value={result.answer}
onChange={(e) => handleInputChange(e, index)}
/>
{results.length !== 1 && (
<button onClick={() => handleRemoveClick(index)}>
Remove
</button>
)}
{results.length - 1 === index && (
<button onClick={handleAddClick}>add</button>
)}
</div>
)
})}
<div style={{ marginTop: 20 }}>{JSON.stringify(results)}</div>
<button onClick={handlesubmit}>submit</button>
</div>
)
}
export default App