本文介绍如何在 react 中实时动态替换模板字符串(如 `"hello ${firstname} ${lastname}"`)中的占位符,支持任意数量的变量,避免因更新顺序导致的覆盖问题。
在构建表单驱动的模板编辑器(如邮件模板、消息生成器)时,一个常见需求是:用户在输入框中修改字段(如 firstName、lastName),页面上预览的模板文本需即时、准确地同步更新所有对应占位符。难点在于——不能仅依赖“最后修改的字段”去替换,而应基于当前完整数据状态对整个模板进行全量、安全、可扩展的替换。
下面是一个健壮、可扩展的实现方案:
import { useState, useEffect } from "react";
export default function TemplateEditor() {
// ✅ 可扩展的数据源:新增字段只需在此对象中添加键值对
const [data, setData] = useState({
firstName: "",
lastName: "",
email: "",
company: ""
});
// ✅ 原始模板(支持任意数量的
${key} 占位符)
const [template, setTemplate] = useState(
"Hi ${firstName} ${lastName}, welcome to ${company}! Contact us at ${email}."
);
// ✅ 实时渲染的最终文本
const [preview, setPreview] = useState(template);
// ✅ 统一处理输入事件
const handleInputChange = (e) => {
const { name, value } = e.target;
setData((prev) => ({ ...prev, [name]: value }));
};
// ✅ 关键逻辑:当 data 变化时,全量重写 preview
useEffect(() => {
let result = template;
Object.keys(data).forEach((key) => {
const placeholder = "${" + key + "}";
// ⚠️ 注意:replace() 默认只替换第一个匹配项,需用 replaceAll() 或正则全局标志
result = result.replaceAll(placeholder, data[key]);
});
setPreview(result);
}, [data, template]);
return (
? 模板预览
{preview}
✏️ 编辑字段
{Object.keys(data).map((key) => (
))}
);
}该方案以「状态聚合 + 全量替换 + 声明式依赖」为核心,彻底规避了按序更新导致的状态覆盖问题,同时具备良好的可维护性与横向扩展能力。无论模板中存在 2 个还是 20 个变量,都能精准、可靠、高效地完成实时渲染。