How to pass form fields from one page to another page in ReactJS?

Checkout.js

This is the checkout.js file. In this file, I returned the Checkout Form, and Now I want to use the form fields of the checkout form page.

The question is how will I get the form fields of the CheckoutForm page and use them on this page which is checkout.js. Because I want to submit the form data in the database. But the form is on another page and the submit button is on another page e.g. (checkout.js page)

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Paper from '@material-ui/core/Paper';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
import Link from '@material-ui/core/Link';
import Typography from '@material-ui/core/Typography';
import AddressForm from './CheckoutForm';
import PaymentForm from './PaymentForm';
import Review from './Review';



function Copyright() {
    return (
        <Typography variant="body2" color="textSecondary" align="center">
            {'Copyright © '}
            <Link color="inherit" href="https://material-ui.com/">
                Your Website
      </Link>{' '}
            {new Date().getFullYear()}
            {'.'}
        </Typography>
    );
}
const useStyles = makeStyles((theme) => ({
    appBar: {
        position: 'relative',
    },

    layout: {
        width: 'auto',
        marginLeft: theme.spacing(2),
        marginRight: theme.spacing(2),
        [theme.breakpoints.up(1000 + theme.spacing(2) * 2)]: {
            width: 1100,
            marginLeft: 'auto',
            marginRight: 'auto',

        },

    },
    paper: {
        marginTop: theme.spacing(3),
        marginBottom: theme.spacing(3),
        padding: theme.spacing(2),
        [theme.breakpoints.up(700 + theme.spacing(3) * 2)]: {
            marginTop: theme.spacing(6),
            marginBottom: theme.spacing(6),
            padding: theme.spacing(3),
            backgroundColor: 'rgb(248, 246, 244)',

        },

    },
    stepper: {
        padding: theme.spacing(5, 0, 5),
        fontWeight: 'bold',
        backgroundColor: 'rgb(248, 246, 244)',


    },
    buttons: {
        display: 'flex',
        justifyContent: 'flex-end',

    },
    button: {
        marginTop: theme.spacing(3),
        marginLeft: theme.spacing(1),
        border: "none"    
    },
}));

const steps = ['Shipping address', 'Payment details', 'Review your order'];

function getStepContent(step) {
    switch (step) {
        case 0:
            return <AddressForm/>;
        case 1:
            return <PaymentForm />;
        case 2:
            return <Review />;
        default:
            throw new Error('Unknown step');
    }
}

export default function Checkout(props) {
    const classes = useStyles();
    const [activeStep, setActiveStep] = React.useState(0);

    const handleNext = () => {
        setActiveStep(activeStep + 1);
    

    };

    const handleBack = () => {
        setActiveStep(activeStep - 1);
    };

    return (
        <React.Fragment>
            <CssBaseline />
            <AppBar position="absolute" color="default" className={classes.appBar}></AppBar>
            <main className={classes.layout}>
                <Paper className={classes.paper}>
                    <Typography component="h1" variant="h3" align="center">
                        Checkout
          </Typography>
                    <Stepper activeStep={activeStep} className={classes.stepper}>
                        {steps.map((label) => (
                            <Step key={label}>
                                <StepLabel><Typography component="h1" variant="h5" align="center">
                                    {label} </Typography></StepLabel>
                            </Step>
                        ))}
                    </Stepper>

                    <React.Fragment>
                        {activeStep === steps.length ? (
                            <React.Fragment>
                                <Typography variant="h5" gutterBottom>
                                    Thank you for your order.
                </Typography>
                                <Typography variant="subtitle1">
                                    Your order number is #2001539. We have emailed your order 
                                     confirmation, and will
                                     send you an update when your order has shipped.
                </Typography>
                            </React.Fragment>
                        ) : (
                                <React.Fragment>
                                    {getStepContent(activeStep)}
                              {    <div className={classes.buttons}>
                                        {activeStep !== 0 && (
                                            <Button variant="contained" style={{outline: 'none'}} 
                                        onClick={handleBack} className={classes.button}>
                                                Back
                                            </Button>
                                        )}
                                        <Button style={{outline: 'none'}}
                                            variant="contained"
                                            color="secondary"
                                            onClick={handleNext}
                                            className={classes.button}
                                        >
                                            {activeStep === steps.length - 1 ? 'Place order' : 'Next'}
                                        </Button>
                                    </div> }
                                </React.Fragment>
                            )}
                    </React.Fragment>
                </Paper>
                <Copyright />
            </main>
        </React.Fragment>
    );
}

CheckoutForm.js

In this file I used the Form I want to access this form fields ( for example first name, last name, and other fields ) in the checkout.js file. How can I do that? Any suggestions?

import React from 'react';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import './CheckoutForm.scss'
import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';


export default function AddressForm() {
  const useStyles = makeStyles((theme) => ({
  buttons: {
    display: 'flex',
    justifyContent: 'flex-end',

},
button: {
    marginTop: theme.spacing(3),
    marginLeft: theme.spacing(1),
    border: "none"    
},
}));

const classes = useStyles();

  return (
    <React.Fragment>
      <Typography variant="h4" gutterBottom>
        Customer Information
      </Typography><br /><br />

      <Grid container fluid spacing={3} >
        <Grid item xs={12} sm={6} >
          <label for="Firstname">Firstname</label>
          <input type="text" class="form-control" id="inputFirstName" placeholder="Firstname" />

        </Grid>
        <Grid item xs={12} sm={6}>
          <label for="Lastname">Lastname</label>
          <input type="text" class="form-control" id="inputLastName" placeholder="Lastname" />

        </Grid>
        <Grid item xs={12}>
          <label for="Address">Address</label>
          <input type="text" class="form-control" id="inputAddress" placeholder="Address" />

        </Grid>
        <Grid item xs={12} sm={6}>
          <label for="City">City</label>
          <input type="text" class="form-control" id="inputCity" placeholder="City" />

        </Grid>

        <Grid item xs={12} sm={6}>
          <label for="State">State</label>

          <select id="inputState" class="form-control">
            <option>Pakistan</option>
          </select>
        </Grid>
      </Grid>
    
    </React.Fragment>
  );
}



Answer

Here is my suggestion, you pass addressValues object and changeAddressValue function to CheckoutForm.js from checkout.js, addressValues is an object that has all values that user fills in the AddressForm i.e firstname, lastname, address etc, this object is controlled by a state in checkout.js, whenever user changes a value in the AddressForm/CheckoutForm, changeAddressValue function updates a values – addressFormValues in the checkout.js, this will make it easy when you submit the form on checkout.js because all the values will have already been populated on the addressFormValues state i.e const [addressFormValues, setAddressFormValues] = React.useState({});

Here is my solution:

CheckoutForm.js

/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import React from 'react';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import './CheckoutForm.scss';
import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles((theme) => ({
  buttons: {
    display: 'flex',
    justifyContent: 'flex-end',

  },
  button: {
    marginTop: theme.spacing(3),
    marginLeft: theme.spacing(1),
    border: "none"    
  },
}));

const AddressForm = ({ addressValues, changeAddressValue }) => {

  const classes = useStyles();

  return (
    <React.Fragment>
      <Typography variant="h4" gutterBottom>
        Customer Information
      </Typography><br /><br />

      <Grid container fluid spacing={3} >
        <Grid item xs={12} sm={6} >
          <label for="Firstname">Firstname</label>
          <input type="text" class="form-control" id="inputFirstName" placeholder="Firstname"  value={addressValues.firstname} onChange={(e) => changeAddressValue('firstname', e.target.value)} />

        </Grid>
        <Grid item xs={12} sm={6}>
          <label for="Lastname">Lastname</label>
          <input type="text" class="form-control" id="inputLastName" placeholder="Lastname" value={addressValues.lastname} onChange={(e) => changeAddressValue('lastname', e.target.value)} />

        </Grid>
        <Grid item xs={12}>
          <label for="Address">Address</label>
          <input type="text" class="form-control" id="inputAddress" placeholder="Address" value={addressValues.address} onChange={(e) => changeAddressValue('address', e.target.value)} />

        </Grid>
        <Grid item xs={12} sm={6}>
          <label for="City">City</label>
          <input type="text" class="form-control" id="inputCity" placeholder="City" value={addressValues.city} onChange={(e) => changeAddressValue('city', e.target.value)} />

        </Grid>

        <Grid item xs={12} sm={6}>
          <label for="State">State</label>

          <select id="inputState" class="form-control" >
            <option>Pakistan</option>
          </select>
        </Grid>
      </Grid>
    
    </React.Fragment>
  );
};

export default AddressForm;

PaymentForm.js

import React from 'react';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import { createStyles } from '@material-ui/core/styles';
import StripeCheckout from 'react-stripe-checkout';
import 'react-toastify/dist/ReactToastify.css';


const styles = createStyles({
  formControlLabel: {
    fontSize: '1.5rem',
    '& label': { fontSize: '5rem' }
  }
});

const handleToken = (token) => {

  console.log(token);
};

const PaymentForm = ({ paymentFormValues, changePaymentFormValue }) => {

  return (
    <React.Fragment>
      <Typography variant="h4" gutterBottom>
                Payment method
      </Typography><br />
      <Grid container spacing={3}>
        <Grid item xs={12}>
          <FormControlLabel
            control={<Checkbox checked={paymentFormValues['checkedA']} onChange={(e) => changePaymentFormValue('checkedA', e.target.checked)} />}
            label={<Typography style={styles.formControlLabel}>Cash on 
                 delivery</Typography>}
          />
        </Grid>
        <Grid item xs={12}>
          <StripeCheckout
            stripeKey="pk_test_51I9XPQAesAg2GfzQyVB7VgP0IbmWwgcfeFJSuCpB2kbNu60AFTbFhC7dxwje8YF4w2ILMJ6o2InB9ENczpd4dCSa00e09XoDbw"
            token={handleToken}
            amount={2 * 100}
            name="All Products"

          />
        </Grid>
      </Grid>
    </React.Fragment>
  );
};

export default PaymentForm;

Checkout.js

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Paper from '@material-ui/core/Paper';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
import Link from '@material-ui/core/Link';
import Typography from '@material-ui/core/Typography';
import AddressForm from './CheckoutForm';
import PaymentForm from './PaymentForm';
import Review from './Review';


const useStyles = makeStyles((theme) => ({
  appBar: {
    position: 'relative',
  },

  layout: {
    width: 'auto',
    marginLeft: theme.spacing(2),
    marginRight: theme.spacing(2),
    [theme.breakpoints.up(1000 + theme.spacing(2) * 2)]: {
      width: 1100,
      marginLeft: 'auto',
      marginRight: 'auto',

    },

  },
  paper: {
    marginTop: theme.spacing(3),
    marginBottom: theme.spacing(3),
    padding: theme.spacing(2),
    [theme.breakpoints.up(700 + theme.spacing(3) * 2)]: {
      marginTop: theme.spacing(6),
      marginBottom: theme.spacing(6),
      padding: theme.spacing(3),
      backgroundColor: 'rgb(248, 246, 244)',

    },

  },
  stepper: {
    padding: theme.spacing(5, 0, 5),
    fontWeight: 'bold',
    backgroundColor: 'rgb(248, 246, 244)',


  },
  buttons: {
    display: 'flex',
    justifyContent: 'flex-end',

  },
  button: {
    marginTop: theme.spacing(3),
    marginLeft: theme.spacing(1),
    border: "none"    
  },
}));

const steps = ['Shipping address', 'Payment details', 'Review your order'];

function Copyright() {
  return (
    <Typography variant="body2" color="textSecondary" align="center">
      {'Copyright © '}
      <Link color="inherit" href="https://material-ui.com/">
                  Your Website
      </Link>{' '}
      {new Date().getFullYear()}
      {'.'}
    </Typography>
  );
}

function getStepContent(step, formValues = null, changeFormValue = null) {
  switch (step) {
  case 0:
    return <AddressForm addressValues={formValues} changeAddressValue={changeFormValue} />;
  case 1:
    return <PaymentForm paymentFormValues={formValues} changePaymentFormValue={changeFormValue}  />;
  case 2:
    return <Review />;
  default:
    throw new Error('Unknown step');
  }
}

export default function Checkout(props) {
  const classes = useStyles();
  const [paymentFormValues, setPaymentFormValues] = React.useState({});
  const [addressFormValues, setAddressFormValues] = React.useState({});
  const [activeStep, setActiveStep] = React.useState(0);

  const handleNext = () => {
    setActiveStep(activeStep + 1);
  };

  const handleBack = () => {
    setActiveStep(activeStep - 1);
  };

  const changeAddressFormValue = (key, value) => {
    let values = { ...addressFormValues };
    values[key] = value;
    setAddressFormValues(values);
  };

  const changePaymentFormValue = (key, value) => {
    let values = { ...paymentFormValues };
    values[key] = value;
    setPaymentFormValues(values);
  };

  return (
    <React.Fragment>
      <CssBaseline />
      <AppBar position="absolute" color="default" className={classes.appBar}></AppBar>
      <main className={classes.layout}>
        <Paper className={classes.paper}>
          <Typography component="h1" variant="h3" align="center">
                        Checkout
          </Typography>
          <Stepper activeStep={activeStep} className={classes.stepper}>
            {steps.map((label) => (
              <Step key={label}>
                <StepLabel><Typography component="h1" variant="h5" align="center">
                  {label} </Typography></StepLabel>
              </Step>
            ))}
          </Stepper>

          <React.Fragment>
            {activeStep === steps.length ? (
              <React.Fragment>
                <Typography variant="h5" gutterBottom>
                                    Thank you for your order.
                </Typography>
                <Typography variant="subtitle1">
                                    Your order number is #2001539. We have emailed your order 
                                     confirmation, and will
                                     send you an update when your order has shipped.
                </Typography>
              </React.Fragment>
            ) : (
              <React.Fragment>
                {
                  activeStep === 0 ? 
                    getStepContent(activeStep, addressFormValues, changeAddressFormValue)
                    : activeStep === 1 ?  getStepContent(activeStep, paymentFormValues, changePaymentFormValue)
                      : getStepContent(activeStep)
                }
                {activeStep === 0 ? <Button onClick={() => {
                  // All the address values will be availabe in addressFormValues object for further processes
                  console.log(addressFormValues);
                }} >Submit Address</Button> : null}
                {    <div className={classes.buttons}>
                  {activeStep !== 0 && (
                    <Button variant="contained" style={{outline: 'none'}} 
                      className={classes.button}
                      onClick={handleBack}
                    >
                        Back
                    </Button>
                  )}
                  <Button style={{outline: 'none'}}
                    variant="contained"
                    color="secondary"
                    onClick={handleNext}
                    className={classes.button}
                  >
                    {activeStep === steps.length - 1 ? 'Place order' : 'Next'}
                  </Button>
                </div> }
              </React.Fragment>
            )}
          </React.Fragment>
        </Paper>
        <Copyright />
      </main>
    </React.Fragment>
  );
}

Happy Hacking!

Leave a Reply

Your email address will not be published. Required fields are marked *