我目前正试图为我的React应用程序编写一个通用表单组件。我知道那里有很多很棒的图书馆,但在这一点上,它们对我来说似乎都是过头了。
这里我的主要目标是拥有一个可以使用的<BasicForm>组件,方法是将submit函数作为props传递,并将输入字段和按钮作为children传递,并为每个字段提供验证要求。
我的<BasicForm>组件应该处理表单state、onChange、onBlur、onSubmit等,还应该处理验证(基于我作为children添加的每个输入类型)。
其动机是,每次需要创建新表单时,我都会感到重复,必须一次又一次地管理输入、验证、onChange和submit函数的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>添加源代码以避免这个问题太长,但基本上它用React.Children.map处理所有输入children,它对每种输入都有验证函数,也有处理更改、模糊、提交等的函数。它还为每个输入字段创建了一个state。
问题简介
<BasicForm
submitFunction={props.linkEmailAndPassword}
submitAction={'this.props.submitFunction(this.state.passwordOne)'}
>正如您从上面的片段中看到的那样,为了将submitAction从使用者发送到<BasicForm>,我必须将其包装在一个字符串中,因为它引用的是只存在于<BasicForm>中的state。最重要的是,我需要提交的特定state部件是在<BasicForm>之外(在使用者中)定义的。
使用者定义了state的哪个部分或哪些部分应该提交,并且在每一种情况下都是不同的,因此我不能把它作为一个“通用”state名称,任何<BasicForm>都会作为内置的。
因此,我以字符串的形式发送,在<BasicForm>中,我不得不使用最不推荐的eval(),如下所示:
BasicForm.js
onSubmit(event) {
event.preventDefault();
this.validateAllFields();
eval(this.props.submitAction);
}真题
在这种情况下,eval()有多糟糕?通过这样做,我是否将我的应用程序暴露给了“恶意黑客”?我应该以任何方式消毒它,即使它不是用户输入?还有别的办法可以绕开吗?我真的很高兴,因为每次我需要的时候都不用从头开始构建一个表单。现在,我只关注字段和验证需求。耽误您时间,实在对不起!
附加信息
P.S.:这是一个输入组件TextInput的代码。PasswordInput就像这样。唯一的区别是type='password'
TextInput.js
import React from 'react';
import Label from './Common/Label';
const TextInput = (props) => {
return(
<div>
<Label
name={props.name}
labelText={props.labelText}
>
</Label>
<div>
<input
type='text'
id={props.name}
name={props.name}
placeholder={props.placeholder}
value={props.value}
onChange={props.onChange}
onBlur={props.onBlur}
>
</input>
</div>
{props.isInvalidMsg && <div><span>{props.isInvalidMsg}</span></div>}
</div>
);
};
export default TextInput;发布于 2019-01-29 12:02:30
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数据,这意味着该数据也应作为回调参数传递。
https://stackoverflow.com/questions/54418448
复制相似问题