REACT: SELECT from MYSQL - javascript

i a new user and a new in React world. I need help to solve this situation about a Select with values from mysql DB.
I receive the values, but the select goes in infinite loop.
The error is surely in this file cause server.js works without problem!!
Really thanks for the help, and sorry if it could be a stupid question. I m studying react from one week and i have not found answers on internet
function FormAddMenu({ registerMenu }) {
const [nomeMenuReg, setNomeMenuReg] = useState("");
const [descrizioneMenuReg, setDescrizioneMenuReg] = useState("");
const [prezzoMenuReg, setPrezzoMenuReg] = useState("");
const [disponibilitaMenuReg, setDisponibilitaMenuReg] = useState("");
const [portataMenuReg, setPortataMenuReg] = useState("");
const [addMenu, setAddMenu] = useState({
portataMenuReg: "",
nomeMenuReg: "",
descrizioneMenuReg: "",
prezzoMenuReg: "",
disponibilitaMenuReg: "",
});
const [portate, setPortate] = useState({ value: "", label: "" });
const selectOptions = async () => {
Axios.post("http://localhost:3001/selectPortata").then((response) => {
// console.log("risposta:",response.data)
setPortate(
response.data.map((risp) => ({
...setPortate,
value: risp.value,
label: risp.label,
})),
);
});
};
selectOptions();
console.log("portate:", portate);
const submitHandler = (e) => {
e.preventDefault();
registerMenu(addMenu);
document.getElementById("addmenu").reset();
};
const handleCheckbox = (e) => {
console.log(e.target.checked);
if (e.target.checked === true) {
setAddMenu({ ...addMenu, disponibilitaMenuReg: 1 });
} else {
setAddMenu({ ...addMenu, disponibilitaMenuReg: e.target.value });
}
};
return (
<div className="container width85">
<h1>CREA IL MENU'</h1>
<form id="addmenu">
<div className="mb-3">
<label htmlFor="portataMenuReg" className="form-label">
PORTATA
</label>
<Select
options={portate}
onChange={(e) => setAddMenu({ ...addMenu, portataMenuReg: e.target.value })}
className="mb-3"
/>
</div>
<div className="mb-3">
<label htmlFor="nomeMenuReg" className="form-label">
NOME
</label>
<input
type="text"
onChange={(e) => setAddMenu({ ...addMenu, nomeMenuReg: e.target.value })}
className="form-control"
id="nomeMenuReg"
rows="3"
/>
</div>
<div className="mb-3">
<label htmlFor="descrizioneMenuReg" className="form-label">
DESCRIZIONE
</label>
<textarea
className="form-control"
onChange={(e) =>
setAddMenu({ ...addMenu, descrizioneMenuReg: e.target.value })
}
id="descrizioneMenuReg"
rows="3"
></textarea>
</div>
<div className="mb-3">
<label htmlFor="prezzoMenuReg" className="form-label">
PREZZO
</label>
<input
type="text"
className="form-control"
onChange={(e) => setAddMenu({ ...addMenu, prezzoMenuReg: e.target.value })}
id="prezzoMenuReg"
rows="3"
/>
</div>
<div className="mb-3">
<label htmlFor="disponibilitaMenuReg" className="form-label">
DISPONIBILITA'
</label>
<input
type="checkbox"
value="0"
className="htmlForm-control"
onChange={handleCheckbox}
id="disponibilitaMenuReg"
rows="3"
/>
</div>
<div className="mb-3">
<button type="submit" onClick={submitHandler} className="btn btn btn-danger">
AGGIUNGI AL MENU
</button>
</div>
</form>
</div>
);
}
export default FormAddMenu;

Wrap the selectOptions(); call in an useEffect (since loading data and mutating state based on it is a side effect).
The empty dependency array (documented above) means the effect is only executed once on mount.
React.useEffect(() => {
selectOptions();
}, []);

Related

dynamic form adding or removing not working after mapping values in react

I made a dynamic form ,but When I save the values ​​that I got with API in ‍haveFaq and map them ,removeFields and addFields does not work
I save the values ​​that I receive from the API in haveFaq like this:
[
{ question: "question1", answer: "answer1" },
{ question: "question2", answer: "answer2" },
{ question: "question3", answer: "answer3" },
];
const [haveFaq, setHaveFaq] = useState([]);
const [tempData, setTempData] = useState([
{
question: "",
answer: "",
},
]);
const handleFormChange2 = (event, index) => {
let data = [...tempData];
data[index][event.target.name] = event.target.value;
setTempData(data);
};
const addFields = () => {
let object = {
question: "",
answer: "",
};
setTempData([...tempData, object]);
};
const removeFields = (index) => {
let data = [...tempData];
data.splice(index, 1);
setTempData(data);
};
Attention
But if we map tempData instead of haveFaq The form works correctly,Because its initial values ​​are empty
<>
{haveFaq.map((form, index) => {
return (
<div key={index + 1}>
<div className="form-row">
<div className="col-md-11 mb-3">
<label className="font-weight-bold" for="">
question
</label>
<input
className="form-control"
name="question"
placeholder="question"
onChange={(event) => handleFormChange2(event, index)}
value={form.question}
/>
</div>
<div className="col-md-1 mt-4 iconSelf">
<p
className="btnRemove"
type="button"
onClick={() => removeFields(index)}
>
❌
</p>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<label className="font-weight-bold" for="">
answer
</label>
<textarea
rows={5}
className="lineHeightAnswer form-control"
name="answer"
placeholder="answer"
onChange={(event) => handleFormChange2(event, index)}
value={form.answer}
/>
</div>
</div>
<hr />
</div>
);
})}
<div>
<button
className="btn btn-info"
type="button"
onClick={addFields}
>
Add New
</button>
</div>
</>

how to add validation to a reactjs form

I have developed a registration form and I tried using validation format but it is not working. I don't know how and where to code a function for it and apply it. please help me how to do it. I will attach the code i have done till now.
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = () => {
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form">
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button onClick={postData} type='submit'>Submit</Button>
</Form>
</div>
)
}
There are good libraries out there, that can help you with form validation before allowing a user to submit the form.
One such library could be formik together with Yup.
This is how I do client side form validation on my forms:
Login schema (made with Yup):
import * as Yup from 'yup';
const loginSchema = Yup.object().shape({
username: Yup.string()
.min(3, 'Minimum 3 chars')
.max(50, 'Max 50 chars')
/* password: Yup.string()
.min(6, 'Minimum 6 chars')
.max(50, 'Max 50 chars')
*/
});
Login component:
export const Login = () => {
const [loading, setLoading] = useState(false);
const formik = useFormik({
initialValues: {
username: ''
},
validationSchema: loginSchema,
onSubmit: async (values, {setStatus, setSubmitting}) => {
setLoading(true);
setStatus(null);
try {
// Call your API function to post to the backend here
// You can access your form values in the "values" parameter
setLoading(false);
} catch (error) {
console.error(error);
setStatus('User not found');
setSubmitting(false);
setLoading(false);
}
}
});
}
return (
<form
onSubmit={formik.handleSubmit}
className={'auth-form-wrapper'}
>
{/* begin::Heading */}
<div className={'auth-form-header'}>
<h1>Log in</h1>
<div className={'auth-error-message-container'}>
formik.status && (
<p className={'error-message'}>{formik.status}</p>
)
}
</div>
</div>
{/* end::Heading */}
{/* begin::Form group content */}
<div className={'auth-form-content'}>
{/* begin::Form group */}
<div className={'dynamic-input-container'}>
<input type='text'
id="username"
value={formik.values.username}
onChange={formik.handleChange}
placeholder='Username'
className={'dynamic-input auth-input ' + clsx(
{'is-invalid': formik.touched.username && formik.errors.username},
{
'is-valid': formik.touched.username && !formik.errors.username
}
)}
autoComplete='off'
/>
{formik.touched.username && formik.errors.username && (
<div className='fv-plugins-message-container'>
<span role='alert'>{formik.errors.username}</span>
</div>
)}
</div>
{/* end::Form group*/}
{/* begin::Action */}
<div className='auth-btn-container'>
<Button variant="contained" size="medium" type={'submit'} disabled={loading}>
{
!loading ? <span>Continue</span>
:
(
<span className={'auth-spinner-container'}>
<ClipLoader
loading={loading}
size={20}
aria-label='Loading Spinner'
/>
</span>
)
}
</Button>
</div>
{/* end::Action */}
</div>
{/* end::Form group content */}
</form>
);
Please note, that in my example I only have a "username" input, but you can obviously add as many fields as you wish.
Documentation:
Formik: https://formik.org/docs/tutorial
Yup: https://www.npmjs.com/package/yup
clxs: https://www.npmjs.com/package/clsx
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = e => {
e.preventDefault();
if(Employee_name.length == 0) return false;
if(Employee_id.length == 0) return false;
if(Employee_address.length == 0) return false;
if(Employee_post.length == 0) return false;
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form" onSubmit={e => postData(e)}>
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
</div>
)
}
This is updated code from your snippet. try this and let me know what's the progress.
I really appreciate you.

How can I persist updated form data after submit?

So I have some formdata in my react app that I want to persist after I make a put request to the mongodb. Problem is that the change is not visible on page refresh. It is only after I log out and log in again that I can see the updated value in the form.
For example let's say that I want to change my first name from John to Eric. The change will update but not in the form. In the form the value will still be John until I log out and in again.
It feels almost like it has to do with the jwt token but I don't know. Any ideas what the problem can be?
export const Edit = () => {
const navigate = useNavigate();
const user = Cookies.get("access_token");
const [id, setId] = useState(null)
const [firstName, setFirstName] = useState("")
const [lastName, setLastName] = useState("")
const [city, setCity] = useState("")
const [email, setEmail] = useState("")
const checkUser = async () => {
try {
const res = await axios
.get(`${process.env.REACT_APP_API_URL}user/protected`, {
withCredentials: true,
headers: {
Authorization: `Bearer ${user}`,
},
})
console.log(res.data.user);
setId(res.data.user.id)
setFirstName(res.data.user.firstName)
setLastName(res.data.user.lastName)
setCity(res.data.user.city)
setEmail(res.data.user.email)
} catch (error) {
console.warn(error)
}
}
useEffect(() => {
if (!user) {
navigate('/')
} else {
checkUser();
}
}, []);
const updateUser = async () => {
try {
const userData = {
firstName: firstName,
lastName: lastName,
city: city,
email: email
}
const API_URL = `${process.env.REACT_APP_API_URL}user/`;
const userId = id;
const res = await axios.put(API_URL + "/" + userId + "/edit", userData)
setFirstName(res.data.firstName)
setLastName(res.data.lastName)
setCity(res.data.city)
setEmail(res.data.email)
// works and is updated in the database
} catch (error) {
console.warn(error)
}
}
return (
<>
<section className="m-5">
<h1 className="mb-5 text-center">Settings</h1>
<form className="row g-3">
<div className="col-md-6">
<label htmlFor="firstName" className="form-label">
First name
</label>
<p>{formErrors.firstName}</p>
<input
type="text"
className="form-control"
id="firstName"
name="firstName"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="lastName" className="form-label">
Last name
</label>
<p>{formErrors.lastName}</p>
<input
type="text"
className="form-control"
id="lastName"
name="lastName"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="city" className="form-label">
City
</label>
<p>{formErrors.city}</p>
<input
type="text"
className="form-control"
id="city"
name="city"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="email" className="form-label">
Email
</label>
<p>{formErrors.email}</p>
<input
type="email"
className="form-control"
id="email"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="col-12 pt-4 text-center">
<button
type="submit"
className="btn btn-primary btn-lg"
onClick={updateUser}
>
Update
</button>
</div>
<div className="col-12 pt-1 text-center">
<button
type="submit"
className="btn btn btn-lg"
>
<a href="edit/password" className="text-decoration-none">
Change Password
</a>
</button>
</div>
</form>
</section>
</>
);
};
Add user as a dependency to the useEffect's dependency array:
useEffect(() => {
if (!user) {
navigate('/')
} else {
checkUser();
}
}, [user]);

I want to reset my form after clicking submit in reactjs. I have tried making another method. but it does not work

import React,{ useState} from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react';
import axios from 'axios';
const Create = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
Here I am sending data to a mock api I created
const postData = () =>{
axios.post(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData`,{
firstName,
lastName,
checkbox
})
}
This is the method I created to reset the form but it does not work.
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
}
This is my form where on click i am calling resetForm function but it is not resetting it
is sending the data but not resetting the form.
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder='First Name' onChange={(e)=>setFirstName(e.target.value) } />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder='Last Name' onChange={(e)=>setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox id="c1" label='I agree to the Terms and Conditions' onChange={(e)=>setCheckBox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={resetForm}>Submit</Button>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Create;
Actually it will reset the form, the problem is you do not use Controlled Components to show the latest update value in UI
you should bind the value like this:
<input type="text" value={this.state.value} onChange={this.handleChange} />
You can refer the doc here:
https://reactjs.org/docs/forms.html
You can reset your form using the native form.reset() method.
const Create = () => {
const ref = React.useRef(null);
const resetForm = () => ref.current.reset();
return (
<div>
<Form ref={ref}>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder="First Name" onChange={(e) => setFirstName(e.target.value)} />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder="Last Name" onChange={(e) => setLastName(e.target.value)} />
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
<br></br>
<Button onClick={() => navigate(-1)}>Go Back</Button>
</div>
);
};
export default Create;
For that, you have to set value property in your input. Try this
const Create = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [checkbox, setCheckBox] = useState(false);
const postData = () => {
console.log(firstName, lastName, checkbox);
};
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
};
return (
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input
id="f1"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input
id="last1"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
checked={checkbox}
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
</div>
);
};

Resetting React Form values after validation

have that problem with resetting the values of the input fields in the form. and wanted to ask if somebody knows a better and way to do that instead of just making 'useState' for every field...
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('sample_id', 'someother_id', formRef.current, 'user_is')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
setMessage(true);
setEmail("");
setName("");
setSubject("");
setTextarea("");
};
return (
<div className="contact" id="contact">
<div className="left">
<img src="" alt="" />
</div>
<div className="right">
<h2>Kontakt</h2>
<form ref={formRef} onSubmit={handleSubmit}>
<label>Name</label>
<input onChange={(e) => setName(e.target.value)} type="text" placeholder="Name" name="user_name" value={name} />
<label>Email</label>
<input onChange={(e) => setEmail(e.target.value)} type="email" placeholder="Email" name="user_email" value={email} />
<label>Betreff</label>
<input onChange={(e) => setSubject(e.target.value)} type="text" placeholder="Subject" name="user_subject" value={subject} />
<label>Nachricht</label>
<textarea onChange={(e) => setTextarea(e.target.value)} placeholder="Message" name="message" value={textarea} />
<button type="submit">Send</button>
{message && <span>Thanks we will respond ASAP.</span>}
</form>
</div>
</div>
)
}
You could use a single state for all the form values (kinda like we did before functional components)
// this could be outside your component
const initialState = { email: "", name: "", subject: "", textArea: ""};
// declaring your state
const [formState, setFormState] = React.useState(initialState);
and then
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('sample_id', 'someother_id', formRef.current, 'user_is')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
setMessage(true);
setFormState(initialState)
};
You also would have to rewrite your input handlers. Like that :
<input onChange={(e) => setFormState({...formState, name: e.target.value})} type="text" placeholder="Name" name="user_name" value={name} />

Categories

Resources