You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React的Formik表单中从URL提取邮箱地址与公司名称

核心问题说明

你当前的代码存在三个问题导致邮箱提取失败:

  • Formik 默认仅在首次渲染时读取 initialValues,后续通过 useEffect 更新邮箱状态后,Formik 不会自动同步更新表单初始值
  • URL 解析逻辑错误,你直接把 ? 后的所有内容作为邮箱,没有拆分后续的 campaign 参数,也没有正确提取公司名称
  • React 的状态更新是异步的,setEmail 执行后立刻打印 selectedemail.text 无法拿到最新值,属于 React 正常的执行机制

修复方案

你可以直接在组件初始化阶段完成 URL 解析(不需要额外的 useEffect 和状态存储),同时给 Formik 开启 enableReinitialize 配置适配动态初始值,适配你给出的固定URL格式的完整代码如下:

// @ts-ignore
import React, { useState } from 'react';
import { Formik, Form, Field } from 'formik';
import { Typography, Button, Grid } from '@material-ui/core';
import * as Yup from 'yup';
import { MyInput } from './comman/MyInput';
import { Textarea } from './comman/Textarea';
import { Event } from '../Tracking/Event';

const contactSchema = Yup.object().shape({
  name: Yup.string().required('Please Enter Your Name'),
  email: Yup.string()
    .email('Please enter a valid email address')
    .required('Please enter an email address'),
  number: Yup.string()
    .min(10, 'Must be 10 digit.')
    .max(10, 'Must be 10 digit.'),
});

export default function ContactUs(props: any) {
  const [state, setState] = useState({
    msg: '',
  });

  // 新增:直接解析URL获取邮箱和公司名,适配你给出的URL格式
  const queryStr = window.location.href.split('?')[1] || '';
  const queryParts = queryStr.split('&');
  // 提取邮箱:?后第一个&前的内容就是邮箱
  const initEmail = queryParts[0] || '';
  // 提取公司名:从abccampaign参数里按%拆分取第三段
  let initCompany = '';
  if (queryParts[1]) {
    const campaignParts = queryParts[1].split('=')[1]?.split('%') || [];
    initCompany = campaignParts[2] || '';
  }

  return (
    <div>
      <img
        src="public/abc.png"
        width="200"
        className="d-inline-block"
        alt="Viser"
        style={{
          marginTop: '2em',
          marginBottom: '2em',
          float: 'right',
        }}
      />
      {/* 新增enableReinitialize配置,允许动态更新初始值 */}
      <Formik
        enableReinitialize={true}
        initialValues={{
          name: '',
          email: initEmail,
          number: '',
          companyname: initCompany,
          message: '',
        }}
        validationSchema={contactSchema}
        onSubmit={(values, { resetForm }) => {
          const data = {
            name: values.name,
            email: values.email,
            number: values.number,
            companyname: values.companyname,
            message: values.message,
            formtype: 'Contactus',
          };
          console.log(data);
          const request = new Request(
            `${process.env.REACT_APP_PRODUCTION_EMAILCONTACTUS_API}`,
            {
              method: 'POST',
              headers: new Headers({
                'Content-Type': 'application/json',
              }),
              body: JSON.stringify(data),
            },
          );

          fetch(request)
            .then((res) => res.json())
            .then((data) => {
              if (data.message === 'Thanks!') {
                setState({
                  msg: data.message,
                });
              } else {
                console.log('error');
              }
            });
          resetForm();
        }}
      >
        {({ errors, touched }) => (
          <Grid container>
            <Grid item xs={12}>
              <Typography
                variant="body1"
                style={{
                  marginTop: '1em',
                  fontFamily: 'roboto',
                  fontSize: '1.3rem',
                  color: '#2F4858',
                }}
              >
                To know more please submit your information, and one of our
                expert advisors will get in touch within 24 hours! 
              </Typography>
              <br />

              <Form>
                <Typography
                  variant="h6"
                  style={{
                    fontFamily: 'roboto',
                    color: '#2F4858',
                    marginTop: '0.5em',
                  }}
                >
                  Full Name
                </Typography>
                <Field
                  id="outlined-multiline-flexible"
                  type="text"
                  name="name"
                  placeholder="Name"
                  component={MyInput}
                />
                <br />
                {errors.name && touched.name ? (
                  <div className="text-danger" style={{ color: 'red' }}>
                    {errors.name}
                  </div>
                ) : null}
                <Typography
                  variant="h6"
                  style={{ fontFamily: 'roboto', marginTop: '1em' }}
                >
                  Email
                </Typography>
                <Field
                  type="email"
                  name="email"
                  placeholder="Email"
                  style={{ color: 'white' }}
                  component={MyInput}
                /> 
                <br />
                {errors.email && touched.email ? (
                  <div className="text-danger" style={{ color: 'red' }}>
                    {errors.email}
                  </div>
                ) : null}
                <Typography
                  variant="h6"
                  style={{
                    fontFamily: 'roboto',
                    color: '#2F4858',
                    marginTop: '1em',
                  }}
                >
                  Mobile Number (Optional)
                </Typography>
                <Field
                  name="number"
                  placeholder="Contact Number"
                  component={MyInput}
                />
                <br />
                {errors.number && touched.number ? (
                  <div className="text-danger" style={{ color: 'red' }}>
                    {errors.number}
                  </div>
                ) : null}
                <Typography
                  variant="h6"
                  style={{
                    fontFamily: 'roboto',
                    color: '#2F4858',
                    marginTop: '1em',
                  }}
                >
                  Company Name (Optional)
                </Typography>
                <Field
                  name="companyname"
                  placeholder="Company Name"
                  component={MyInput}
                />
                <br />
                <Typography
                  variant="h6"
                  style={{
                    fontFamily: 'roboto',
                    color: '#2F4858',
                    marginTop: '1em',
                  }}
                >
                  How can we help? (Optional)
                </Typography>
                <Field
                  id="outlined-multiline-static"
                  name="message"
                  placeholder="Your question about our services"
                  label="How can we help?"
                  component={Textarea}
                />
                <br />
                <br />
                <Button
                  type="submit"
                  variant="contained"
                  style={{
                    background: '#F79924',
                    color: 'white',
                    fontFamily: 'roboto',
                    fontSize: '1rem',
                  }}
                >
                  Submit 
                </Button>
                <br />
                {state.msg && (
                  <Typography
                    variant="h6"
                    style={{
                      color: '#4BB543',
                      fontFamily: 'roboto-medium',
                      marginTop: '1em',
                    }}
                  >
                     {state.msg} 
                  </Typography>
                )}
              </Form>
            </Grid>
          </Grid>
        )}
      </Formik>
    </div>
  );
}

改动说明

  • 删掉了冗余的 selectedemail 状态和对应的 useEffect,直接在组件初始化时解析URL,减少不必要的状态更新
  • 新增了适配你给出的URL格式的解析逻辑,同时提取邮箱和公司名,没有对应参数时默认返回空字符串
  • 给Formik新增了 enableReinitialize={true} 配置,如果你后续需要动态修改初始值也可以正常生效
  • 删掉了Field组件里无效的 values={props.text} 属性,避免干扰Formik的默认值逻辑

内容的提问来源于stack exchange,提问作者sudesh sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 05:06:03