Javascript 条件反应呈现
我有一个来自React的简单表单构建。提交后,如果返回错误,我希望提供一个额外的div以在表单上显示错误 现在我让它工作,但我不喜欢这个解决方案。我的解决方案基于这样一种认识,即只有在呈现函数内部的状态发生变化时,组件才会重新呈现(在本例中为.state.errorMessages)。因此,我必须像这样显式地将if条件放在渲染函数中Javascript 条件反应呈现,javascript,reactjs,Javascript,Reactjs,我有一个来自React的简单表单构建。提交后,如果返回错误,我希望提供一个额外的div以在表单上显示错误 现在我让它工作,但我不喜欢这个解决方案。我的解决方案基于这样一种认识,即只有在呈现函数内部的状态发生变化时,组件才会重新呈现(在本例中为.state.errorMessages)。因此,我必须像这样显式地将if条件放在渲染函数中 renderError() { var errArr = []; for (var key in this.state.errorMessages)
renderError() {
var errArr = [];
for (var key in this.state.errorMessages) {
errArr = [...errArr, ...this.state.errorMessages[key]];
}
return (
<div className="alert alert-danger">
{errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
renderForm() {
return (
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" name="name" placeholder="Name" value={this.state.firstName} onChange={this.handleFirstNameChange} required/>
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleLastNameChange} required/>
</div>
<div className="form-group">
<label>Email address</label>
<input type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={this.state.email} onChange={this.handleEmailChange} />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
</div>
<div className="form-group">
<label>Password Confirmation</label>
<input type="password" className="form-control" name="password_confirmation" placeholder="Password Confirmation" value={this.state.passwordConfirmation} onChange={this.handlePasswordConfirmationChange}/>
</div>
<div>
<button type="submit" className="btn btn-primary">Submit</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>Cancel</button>
</div>
</form>
)
}
render () {
if (!this.state.errorMessages) {
return (
<div>
{this.renderForm()}
</div>
)
} else {
return (
<div>
{this.renderForm()}
{this.renderError()}
</div>
)
}
}
renderError(){
var errArr=[];
for(此.state.errorMessages中的var键){
errArr=[…errArr,…this.state.errorMessages[key]];
}
返回(
{errArr.map((err)=>{
返回{err}
})}
)
}
renderForm(){
返回(
名字
姓
电子邮件地址
我们永远不会与其他人共享您的电子邮件。
暗语
密码确认
提交
取消
)
}
渲染(){
如果(!this.state.errorMessages){
返回(
{this.renderForm()}
)
}否则{
返回(
{this.renderForm()}
{this.renderError()}
)
}
}
我真的不喜欢这种方法,因为如果我有更多的条件重新渲染,这可能会变得很糟糕。我希望有一个解决方案,在实际的渲染函数中没有太多的逻辑,并将其提取出来。例如
renderError() {
if (!this.state.errorMessages) {
return;
}
var errArr = [];
for (var key in this.state.errorMessages) {
errArr = [...errArr, ...this.state.errorMessages[key]];
}
return (
<div className="alert alert-danger">
{errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
render () {
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" name="name" placeholder="Name" value={this.state.firstName} onChange={this.handleFirstNameChange} required/>
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleLastNameChange} required/>
</div>
<div className="form-group">
<label>Email address</label>
<input type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={this.state.email} onChange={this.handleEmailChange} />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
</div>
<div className="form-group">
<label>Password Confirmation</label>
<input type="password" className="form-control" name="password_confirmation" placeholder="Password Confirmation" value={this.state.passwordConfirmation} onChange={this.handlePasswordConfirmationChange}/>
</div>
<div>
<button type="submit" className="btn btn-primary">Submit</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>Cancel</button>
</div>
{this.renderError}
</form>
}
renderError(){
如果(!this.state.errorMessages){
回来
}
var errArr=[];
for(此.state.errorMessages中的var键){
errArr=[…errArr,…this.state.errorMessages[key]];
}
返回(
{errArr.map((err)=>{
返回{err}
})}
)
}
渲染(){
名字
姓
电子邮件地址
我们永远不会与其他人共享您的电子邮件。
暗语
密码确认
提交
取消
{this.renderError}
}
这会引发错误,因为它抱怨应将This.renderError作为函数调用。但当我把它当作
this.renderError()
错误永远不会呈现,因为当错误返回时不会自动调用它
-----------更新----------
或者,为什么我不能像下面这样做
render () {
<div>
<form onSubmit={this.handleRegisterFormSubmit}>
...
</form>
{if (this.state.errorMessages) {this.renderError()}}
</div>
}
render(){
...
{if(this.state.errorMessages){this.renderError()}
}
这会引发控制台错误
未捕获错误:模块生成失败:语法错误:意外令牌
(117:13)
----------更新2-----------
本质上,我正在寻找一种解决方案,在render函数中,当状态改变时,我可以轻松地显示整个代码块。在Vue中,我可以做以下事情
<form>
<input type="text">
</form>
<div v-if="hasError">
<div class="alert alert-danger">{{something}}</div>
</div>
Can I do something as easy as this in React?
{{something}}
我能做一些像这一样简单的事情吗?
您可以使用map从对象中提取错误消息
下面是React中表单验证和错误的一个简单示例。了解它是如何工作的很好,但就我而言,我使用了它简化了这个过程
class Test extends React.Component {
constructor(props) {
super(props);
this.state = { errorMessages: {} };
}
handleRegisterFormSubmit = e => {
e.preventDefault(); // don't submit the form until we run what's below
let errorMessages = {};
if (!this.state.lastName) errorMessages.lastName = 'You need to enter your last name';
// And so on for each field validation
// Do we have errors ?
if (Object.keys(errorMessages).length > 0) {
this.setState(errorMessages);
} else {
// Submit to server
}
};
handleChange = e => {
this.setState({
[e.target.name]: e.target.value,
errorMessages: {
...this.state.errorMessages,
[e.target.name]: null // remove the error of this field if it's being edited
}
});
};
render() {
const errArr = Object.keys(this.state.errorMessages).map(key => this.state.errorMessages[key]);
return (
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleChange} />
</div>
{/* ... your dom */}
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>
Cancel
</button>
</div>
{errArr.length > 0 && (
<div className="alert alert-danger">
{errArr.map(err => {
return <p>{err}</p>;
})}
</div>
)}
</form>
);
}
}
您可以使用map从对象中提取错误消息 下面是React中表单验证和错误的一个简单示例。了解它是如何工作的很好,但就我而言,我使用了它简化了这个过程
class Test extends React.Component {
constructor(props) {
super(props);
this.state = { errorMessages: {} };
}
handleRegisterFormSubmit = e => {
e.preventDefault(); // don't submit the form until we run what's below
let errorMessages = {};
if (!this.state.lastName) errorMessages.lastName = 'You need to enter your last name';
// And so on for each field validation
// Do we have errors ?
if (Object.keys(errorMessages).length > 0) {
this.setState(errorMessages);
} else {
// Submit to server
}
};
handleChange = e => {
this.setState({
[e.target.name]: e.target.value,
errorMessages: {
...this.state.errorMessages,
[e.target.name]: null // remove the error of this field if it's being edited
}
});
};
render() {
const errArr = Object.keys(this.state.errorMessages).map(key => this.state.errorMessages[key]);
return (
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleChange} />
</div>
{/* ... your dom */}
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>
Cancel
</button>
</div>
{errArr.length > 0 && (
<div className="alert alert-danger">
{errArr.map(err => {
return <p>{err}</p>;
})}
</div>
)}
</form>
);
}
}
我相信这是一个建筑问题 尝试遵循这些做法: 1-直接在JSX内注入条件语句 2-使用功能组件呈现JSX而不是对象方法
1-直接在JSX内部注入条件语句 坏:
if (!this.state.errorMessages) {
return (
<div>
{this.renderForm()}
</div>
)
} else {
return (
<div>
{this.renderForm()}
{this.renderError()}
</div>
)
}
我花了两年的时间开发企业应用程序,也是从Udacity毕业的,我在这里分享我的经验。恭喜你 我认为这是一个架构问题 尝试遵循这些做法: 1-直接在JSX内注入条件语句 2-使用功能组件呈现JSX而不是对象方法
1-直接在JSX内部注入条件语句 坏:
if (!this.state.errorMessages) {
return (
<div>
{this.renderForm()}
</div>
)
} else {
return (
<div>
{this.renderForm()}
{this.renderError()}
</div>
)
}
我花了两年的时间开发企业应用程序,也是从Udacity毕业的,我在这里分享我的经验。恭喜你 人们通常会在表示列表的元素中呈现项目,并应用一些样式。如果我们没有任何物品,我们有时也不需要这个包装元素 我已经编写了下面的组件,它允许条件渲染。如果条件为false,则不会呈现保持DOM干净的元素
export default class If extends Component<{ condition: any }, {}> {
render() {
return this.props.condition ? this.props.children : <Fragment></Fragment>;
}
}
如果扩展组件,则导出默认类{
render(){
返回this.props.condition?this.props.children:;
}
}
现在,您可以按如下方式简单地使用该组件:
<If condition={items.length}>
<-- item list -->
</If>
人们通常会在表示列表的元素中呈现项目,并应用一些样式。如果我们没有任何物品,我们有时也不需要这个包装元素 我已经编写了下面的组件,它允许条件渲染。如果条件为false,则不会呈现保持DOM干净的元素
export default class If extends Component<{ condition: any }, {}> {
render() {
return this.props.condition ? this.props.children : <Fragment></Fragment>;
}
}
如果扩展组件,则导出默认类{
render(){
把这个还给我
<If condition={items.length}>
<-- item list -->
</If>