我目前正在尝试为我的React应用程序编写通用表单组件。我知道那里有很多很棒的库,但是就目前而言,它们似乎都对我来说太过强大了。
我的主要目标是拥有一个我可以使用的<BasicForm>
组件,方法是将Submit函数作为props
传递,并将输入字段和按钮作为children
以及验证要求一起传递每个字段。
我的<BasicForm>
组件应处理以下形式:state
,onChange
,onBlur
,onSubmit
等。并且还应处理验证(基于每个输入我添加为children
的类型。
这样做的动机是,每次需要创建state
来进行输入,验证,onChange
和submit
的功能时,每次创建新表单时我都会感到重复。
这是我使用<Basic Form>
的代码:
BasicForm-Consumer.js
<BasicForm
submitFunction={props.linkEmailAndPassword}
submitAction={'this.props.submitFunction(this.state.passwordOne)'}
>
<PasswordInput
labelText='Password'
name='passwordOne'
placeholder='Enter password...'
min={6}
max={12}
required
/>
<TextInput
labelText='Username'
name='username'
placeholder='Enter username...'
initialValue=''
min={5}
max={10}
required
/>
<button type='submit'>Create Password</button>
</BasicForm>
起初,我不会在此处添加<BasicForm>
的源代码,以免使这个问题过长,但基本上它会使用children
处理所有输入React.Children.map
并具有验证性用于每种输入,也可以处理更改,模糊,提交等。它还为每个输入字段创建一个state
。
问题介绍
<BasicForm
submitFunction={props.linkEmailAndPassword}
submitAction={'this.props.submitFunction(this.state.passwordOne)'}
>
从上面的代码段中可以看到,为了将submitAction
从使用者发送到<BasicForm>
,我必须将其包装在字符串中,因为它引用了state
只会存在于<BasicForm>
内部。最重要的是,我需要提交的特定state
部分是在<BasicForm>
之外(在使用者中)定义的。
使用者定义state
的哪一部分应提交,并且在每种情况下都将有所不同,因此我不能将其作为任何{ {1}}将具有内置功能。</ p>
因此,我以字符串形式发送,并且在state
内部,我不得不使用最不推荐的<BasicForm>
,如下所示:
BasicForm.js
<BasicForm>
正确的问题
在这种情况下,eval()
有多糟糕?通过这样做,我是否会将我的应用程序暴露给“恶意黑客”?即使不是用户输入,也应该以任何方式对其进行消毒吗?还有其他解决方法吗?我真的很高兴,不必每次都需要从头开始构建表单。现在,我仅关注字段和验证要求。谢谢您的宝贵时间!
额外信息
P.S .:这是输入组件 onSubmit(event) {
event.preventDefault();
this.validateAllFields();
eval(this.props.submitAction);
}
之一的代码。 eval()
就是这样。唯一的区别是TextInput
:
TextInput.js
PasswordInput
答案 0 :(得分:3)
几乎永远不会评估Eval,因为它会带来安全风险,性能损失并表明存在设计问题。
是否存在安全风险取决于使用情况。如果评估后的表达式有可能直接或间接包含用户输入,则存在安全风险。否则,仅适用于性能和设计方面的问题。
在这种情况下,这意味着BasicForm
无法为父组件提供合理的API,因此最终以eval
结尾。正确的方法是回调。
由于父组件通常不应该了解BasicForm
的实现细节并不能访问其实例,因此BasicForm
this
在回调中不可用。 BasicForm
道具已经在回调中可用-它们在父组件中传递。由于已知BasicForm
state
包含其子输入中的值,因此应该在回调中可用。
所以BasicForm
回调看起来像:
<BasicForm
onSubmit={state => props.linkEmailAndPassword(state.passwordOne)}}
...
onSubmit(event) {
event.preventDefault();
this.validateAllFields();
this.props.onSubmit(this.state);
}
如果需要onSubmit
回调来访问除状态以外的任何BasicForm
数据,这意味着该数据也应作为回调参数传递。