React中替代eval()处理变量名的最佳实践方案咨询
替代eval()的React状态访问方案
方案1:合并相关状态为单个对象(推荐)
你当前把name和paid拆成了两个独立状态,其实可以合并成一个对象,这样能直接通过输入框的name属性对应到状态的键,完全不需要eval:
// 合并状态为一个对象 const [formState, setFormState] = useState({ name: props.expense.name, paid: props.expense.paid }); // 实时更新输入框状态的处理函数 const inputChangeHandler = (e) => { const { name, value } = e.target; setFormState(prev => ({ ...prev, [name]: value })); }; // 失去焦点时的提交处理 const inputBlurHandler = (e) => { const { name } = e.target; updateExpense(id, { [name]: formState[name] }); setSuccGreen("updatedSucc"); };
对应的输入框写法:
<input name="name" type="text" onChange={inputChangeHandler} onBlur={inputBlurHandler} value={formState.name} ... /> <input name="paid" type="text" onChange={inputChangeHandler} onBlur={inputBlurHandler} value={formState.paid} ... />
这种方式不仅去掉了eval,还简化了状态管理,多个输入框可以复用同一个变更处理函数,代码更简洁易维护。
方案2:使用映射对象关联name与对应state(适合不想合并状态的场景)
如果暂时不想合并状态,可以创建一个临时映射对象,把输入框的name和对应的状态值关联起来,替代eval的作用:
const [paidValue, setPaidValue] = useState(props.expense.paid); const [nameValue, setNameValue] = useState(props.expense.name); const inputBlurHandler = (e) => { // 映射输入框name到对应的状态值 const valueMap = { name: nameValue, paid: paidValue }; updateExpense(id, { [e.target.name]: valueMap[e.target.name] }); setSuccGreen("updatedSucc"); };
这种方式同样规避了eval的安全风险,代码可读性也远高于eval,后续新增输入框时,只需在valueMap中添加对应的键值对即可。
为什么要弃用eval?
eval会执行传入的字符串代码,不仅存在XSS等安全隐患,还会降低代码的可读性与可维护性,同时会干扰JavaScript引擎的优化逻辑,影响性能。上面两种方案都能安全高效地实现需求,更符合React的编码规范。
内容的提问来源于stack exchange,提问作者Mohamed Ali Ben Thaier
相关产品推荐
相关产品推荐

