
本文介绍一种基于 react hook 的通用方案,用于实时将表单输入值动态注入模板字符串中的 `${key}` 占位符,支持任意数量的变量(如 `${firstname}`、`${lastname}` 等),避免手动维护多个状态或重复逻辑。
在构建可配置模板编辑器、邮件/短信内容预览、动态文案生成等场景中,常需将用户输入实时映射到模板字符串(如 “Hello ${firstName} ${lastName}”)中。若为每个变量单独声明 useState 并分别监听,代码会迅速变得冗余且难以扩展。更优解是采用统一数据结构 + 响应式更新模式。
核心思路如下:
- 使用一个对象(如 data)集中管理所有变量及其当前值,键名与模板中 ${key} 的 key 严格对应;
- 表单 通过 name 属性自动关联变量名,onChange 统一调用 setData 更新对应字段;
- 利用 useEffect 监听 data 对象变化,遍历其所有键,对模板字符串执行批量 .replace() 替换,确保任意字段更新均触发全文本刷新。
以下是完整实现示例(已适配任意变量数量):
import { useState, useEffect } from "react"; export default function App() { // ✅ 所有变量统一存于 data 对象中,键即模板占位符名 const [data, setData] = useState({ firstName: "", lastName: "", email: "", company: "" // 可无限扩展,无需修改逻辑 }); // ? 原始模板(支持任意数量 ${xxx}) const [template, setTemplate] = useState( "Hi ${firstName} ${lastName}, welcome to ${company}! Contact us at ${email}." ); // ?️ 实时渲染结果 const [renderedText, setRenderedText] = useState(template); // ? 统一输入处理器:根据 input.name 动态更新 data 中对应字段 const handleInputChange = (e) => { const { name, value } = e.target; setData(prev => ({ ...prev, [name]: value })); }; // ⚡ 响应式更新:data 任一字段变化,立即重渲染 template useEffect(() => { let result = template; Object.keys(data).forEach(key => { const placeholder = `${'${'}${key}${'}'}`; // 注意:仅替换首次匹配(避免正则全局污染),如需全部替换可改用正则 /g result = result.replace(placeholder, data[key]); }); setRenderedText(result); }, [data, template]); // 依赖 data 和 template,确保模板变更也触发重算 return (