React refs实现mailto联系表单无法传递输入值问题求助
问题根源
你的代码有4个核心错误,导致功能不符合预期:
useRef是React Hook API,只能在函数组件、自定义Hook的顶层作用域使用。你当前编写的是类组件,还把useRef写在组件外部,完全违反Hook使用规则,ref绑定、取值本身就存在异常。window.open传入的mailto地址是写死的固定字符串,没有拼接你已经获取到的subject、body变量,所以唤起的邮件永远显示固定的占位文本。- render方法里的表单控件绑定的是组件外错误定义的ref,没有绑定到类组件实例的正确ref上,根本拿不到用户输入的实时值。
- 用户输入的内容可能包含空格、换行、&、中文等特殊字符,直接拼接到URL里会出现参数截断、乱码问题,必须做URL编码。
修复后完整代码
首先删掉组件外错误定义的useRef,类组件使用React.createRef()创建实例ref,再把编码后的用户输入拼接到mailto链接中即可:
import React from 'react'; import './index.css'; import * as parts from './UIComponents.js' export class Email extends React.Component { // 类组件正确创建ref的方式,作为类实例属性 subjectRef = React.createRef(); messageRef = React.createRef(); goButton(i) { return(<parts.ButtonFactory onClick={() => this.go()} value={i} />); } go() { // 做空值兼容,避免输入为空时取值报错 const subjectVal = this.subjectRef.current?.value || ''; const bodyVal = this.messageRef.current?.value || ''; // 对用户输入做URL编码,拼接成合法的mailto链接 const mailtoUrl = `mailto:mixedbyinstinct@gmail.com?subject=${encodeURIComponent(subjectVal)}&body=${encodeURIComponent(bodyVal)}`; window.open(mailtoUrl); } render() { return ( <div className="email-form"> <div className="container"> <div className="input-group"> <label>邮件主题:</label> <input type="text" ref={this.subjectRef} /> <br /> <label>详细内容:</label> <textarea rows="8" ref={this.messageRef} /> </div> <div className="btn-group"> {this.goButton('REACH OUT')} </div> </div> </div> ); } }
可选优化
如果你需要保留原来的"Your Name"输入项,可以新增一个对应的ref存储用户姓名,在拼接正文时把姓名加到内容开头即可,示例:
// 新增姓名ref nameRef = React.createRef(); go() { const name = this.nameRef.current?.value || '匿名用户'; const subjectVal = this.subjectRef.current?.value || ''; const contentVal = this.messageRef.current?.value || ''; // 把姓名拼到正文开头 const bodyVal = `发件人:${name}\n\n${contentVal}`; const mailtoUrl = `mailto:mixedbyinstinct@gmail.com?subject=${encodeURIComponent(subjectVal)}&body=${encodeURIComponent(bodyVal)}`; window.open(mailtoUrl); }
内容的提问来源于stack exchange,提问作者MixedByInstinct
相关产品推荐
相关产品推荐

