Alwayslearning
Alwayslearning

Reputation: 113

How to send the Input Fields in React Function component to a function

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

Answers (3)

Nagibaba
Nagibaba

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

Michael
Michael

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

Aravind
Aravind

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

Related Questions