Reputation: 113
I have 4 input fields in my react functional component, I have made a function contactMeButtonPressed, I want to grab all the inputs name, email, company name, message when I click on the contact me button.
Do I need a state in here or I can get to my goal with my code?
contact.js
import React, {Component} from 'react';
import Navbar from "./Navbar";
import {useStyles} from '../../static/styles/styles';
import {TextField, Typography, Button, Grid, Box, withStyles} from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import {WithStyles, makeStyles} from "@material-ui/core/styles";
const InputField = withStyles({
root: {
"& label.Mui-focused": {
color: "tomato",
},
"& label": {
color: "tan",
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
borderColor: "tan",
},
"&:hover fieldset": {
borderColor: "tan"
},
"&.Mui-focused fieldset": {
borderColor: "tan",
}
}
},
})(TextField);
function contactMeButtonPressed() {
const requestOptions = {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
// how to get all the InputField from box component in Contact
}),
};
fetch("/backend/contact-me/", requestOptions)
.then((response) => response.json())
.then((data) => console.log(requestOptions));
}
const Contact = () => {
const classes = useStyles(); // To use the CSS Styles in styles.js
return (
<>
<Box component="div" style={{background: "#233", height: "100vh"}}>
<Navbar/>
<Grid container justify="center">
<Box component="form" className={classes.form}>
<Typography variant="h5" style={{
color: "tomato",
textAlign: "center",
textTransform: "uppercase",
}}
>
Contact me
</Typography>
<InputField
fullWidth={true}
label="Name"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
fullWidth={true}
label="Email"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
fullWidth={true}
label="Company Name"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
fullWidth={true}
label="Message"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<Button
className={classes.contactButton}
variant="outlined"
fullWidth={true}
endIcon={<SendIcon/>}
onClick={contactMeButtonPressed}
>
Contact me
</Button>
</Box>
</Grid>
</Box>
</>
);
};
export default Contact;
code with solution using Hooks:
import React, {Component} from 'react';
import Navbar from "./Navbar";
import {useStyles} from '../../static/styles/styles';
import {TextField, Typography, Button, Grid, Box, withStyles} from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import {WithStyles, makeStyles} from "@material-ui/core/styles";
import {useState} from 'react';
const InputField = withStyles({
root: {
"& label.Mui-focused": {
color: "tomato",
},
"& label": {
color: "tan",
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
borderColor: "tan",
},
"&:hover fieldset": {
borderColor: "tan"
},
"&.Mui-focused fieldset": {
borderColor: "tan",
}
}
},
})(TextField);
const Contact = () => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [company_name, setCompany_name] = useState('')
const [message, setMessage] = useState('')
function contactMeButtonPressed() {
const requestOptions = {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
name: name,
company_name: company_name,
message: message,
email: email,
}),
};
fetch("/backend/contact-me/", requestOptions)
.then((response) => response.json())
.then((data) => console.log(requestOptions));
}
const classes = useStyles(); // To use the CSS Styles in styles.js
return (
<>
<Box component="div" style={{background: "#233", height: "100vh"}}>
<Navbar/>
<Grid container justify="center">
<Box component="form" className={classes.form}>
<Typography variant="h5" style={{
color: "tomato",
textAlign: "center",
textTransform: "uppercase",
}}
>
Contact me
</Typography>
<InputField
value={name}
onChange={e => setName(e.target.value)}
fullWidth={true}
label="Name"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
value={email}
onChange={e => setEmail(e.target.value)}
fullWidth={true}
label="Email"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
value={company_name}
onChange={e => setCompany_name(e.target.value)}
fullWidth={true}
label="Company Name"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<InputField
value={message}
onChange={e => setMessage(e.target.value)}
fullWidth={true}
label="Message"
variant="outlined"
inputProps={{style: {color: "white"}}}
margin="dense"
size="medium"
/>
<br/>
<Button
className={classes.contactButton}
variant="outlined"
fullWidth={true}
endIcon={<SendIcon/>}
onClick={contactMeButtonPressed}
>
Contact me
</Button>
</Box>
</Grid>
</Box>
</>
);
};
export default Contact;
Upvotes: 1
Views: 1014
Reputation: 5358
A better way is using formik
as it will create a global variable that can be easily adapted to client-side validation (Ex. yup
) and it will handle onSubmit
, field value change and error handling.
import React from 'react';
import { useFormik } from 'formik';
const SignupForm = () => {
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="firstName">First Name</label>
<input
id="firstName"
name="firstName"
type="text"
onChange={formik.handleChange}
value={formik.values.firstName}
/>
<label htmlFor="lastName">Last Name</label>
<input
id="lastName"
name="lastName"
type="text"
onChange={formik.handleChange}
value={formik.values.lastName}
/>
<label htmlFor="email">Email Address</label>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<button type="submit">Submit</button>
</form>
);
};
https://formik.org/docs/api/useFormik
You can even use its context (useFormikContext
) to pass field values without passing it to components
Upvotes: 0
Reputation: 1674
In Material your InputField
component can have an id tag, so what I would do is set an id on the InputField component and then when you click your contactMeButtonPressed you can get all of the fields like so:
function contactMeButtonPressed() {
const Name = document.getElementByID('name').value;
const Email = document.getElementByID('email').value;
const Company Name = document.getElementByID('company-name').value;
const Message = document.getElementByID('message').value;
const requestOptions = {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
// how to get all the InputField from box component in Contact
}),
};
fetch("/backend/contact-me/", requestOptions)
.then((response) => response.json())
.then((data) => console.log(requestOptions));
}
and then format those values into what your db is expecting.
Upvotes: 1
Reputation: 680
Yes you need state to manage the data in reactjs. Since, you are using functional component it's very easy to manage the data. you can use useState
to manage a data. I'll show you an example to manage a data in react wiht input.
import the use state using following command
import React, {useState} from 'react';
following command use to declare state variable.
const [text, setText] = useState('')
following command is the declaration of input.
<input
value={text}
onChange={e => setText(e.target.value)}
required
></input>
At the end your data will be stored in text state you use that to send the data to backend.
Upvotes: 2