1

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?

  • Right now I'm printing on the console for testing, later I will send the information to my Django backend.

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;
0

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Does that mean I need usestate function for each input? and how can I send all the values to my contactMeButtonPressed function so I can send them to my backend? I haven't learned hooks yet but I am reading on them now
@Alwayslearning after adding the above snippets and hooks in your code now the input tab is set to store the values in state. After typing any value in Input field for example if you're typing "abc" there then "abc" stores in text you can use that throught the component or you can pass it to another component. It's almost same like global variable to the component.
It seem to work, I have added the update code would appreciate it if you take a look if i have used them right
1

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.

2 Comments

Thank You for your time! I used Hooks in the end it seems working for now, Added the updated code
Personally I don't think you need to use any state in your component for this to work since you can just get the information from the input field using the id, but i'm glad to have helped.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.