
本文介绍在 React 项目中安全、高效地实现类似模板字符串的变量替换功能,支持嵌套对象路径(如 ${component.name}),无需引入 Handlebars 等重型库,纯 JavaScript 方案即可完成。
本文介绍在 react 项目中安全、高效地实现类似模板字符串的变量替换功能,支持嵌套对象路径(如 `${component.name}`),无需引入 handlebars 等重型库,纯 javascript 方案即可完成。
在 React 开发中,有时需要将含占位符的字符串(如 "component=\"${component.name}\" and id=${id}")根据运行时数据动态渲染。由于 React 默认不支持服务端模板语法,且 eval 或 Function 构造函数存在安全与性能风险,推荐采用可预测、可维护、零依赖的函数式方案。
✅ 推荐方案:自定义安全解析函数
使用正则匹配 ${...} 占位符,并通过安全的路径访问函数(如 _.get 或手写 deepGet)提取值,避免 eval 和原型污染风险:
// 工具函数:安全获取嵌套属性值
const deepGet = (obj: any, path: string, defaultValue: any = undefined): any => {
return path.split('.').reduce((current, key) => {
return current && typeof current === 'object' ? current[key] : undefined;
}, obj) ?? defaultValue;
};
// 主解析函数
const interpolate = (template: string, data: Record<string, any>): string => {
return template.replace(/\$\{([^}]+)\}/g, (_, path) => {
const value = deepGet(data, path.trim());
return value === undefined ? '' : String(value);
});
};
// 使用示例
const message = 'component="${component.name}" and id=${id}';
const data = { id: 101, component: { name: 'Shiv' } };
console.log(interpolate(message, data));
// 输出:'component="Shiv" and id=101'⚠️ 注意事项
- 禁止使用 eval 或 new Function():易导致 XSS 漏洞(尤其当 template 来自用户输入时);
- 路径安全性:deepGet 显式限制为点号分隔的属性访问,不支持任意表达式(如 ${id + 1}),保障沙箱隔离;
- React 中使用建议:将 interpolate 封装为自定义 Hook(如 useInterpolatedText),便于复用与 memoization;
- 空值处理:默认返回空字符串,也可按需抛出错误或保留原始占位符(如 ${missing} → undefined)。
? 进阶提示
若需支持更复杂语法(如条件、循环),可考虑轻量级模板引擎如 mustache.js(无逻辑、纯渲染)或 eta(服务端/客户端通用),但对简单变量替换,上述 interpolate 函数已足够健壮、清晰且零依赖。
总之,拥抱 JavaScript 原生能力,结合函数式思维,就能在 React 中优雅解决动态字符串渲染问题。


















