我的概念是制作一个包含Form
的{{1}},如果未填写任何必需的FormElements
,则其所有者FormElements
会知道该信息。因为我是React的新手,所以我无法理解如何让他们进行沟通。这是我到目前为止的一点:
Form
然后使用表格:
Form = React.createClass({
getInitialState() {
return {
validated: false
}
},
render() {
return (
<form id={this.props.id}>
{this.props.children}
</form>
)
},
componentDidMount() {
React.Children.forEach(this.props.children, function (el) {
if (el.props.type === 'submit') {
console.log(el);
$(el).prop('disabled', true);
}
});
}
});
FormElement = React.createClass({
propTypes: {
id: React.PropTypes.string.isRequired,
label: React.PropTypes.string.isRequired,
type: React.PropTypes.string,
required: React.PropTypes.bool
},
getDefaultProps() {
return {
type: 'text',
required: false
}
},
getInitialState() {
return {
focused: false,
filled: false,
touched: false
}
},
handleFocus(focused) {
this.setState({focused, touched: true});
},
handleKeyUp(event) {
this.setState({filled: event.target.value.length > 0});
},
render() {
let formElement;
if (_.contains(['text', 'email', 'password'], this.props.type)) {
formElement = (
<div className="form-group">
<label className={this.state.focused || this.state.filled ? "focused" : ""}
htmlFor={this.props.id}>{this.props.label}</label>
<input type={this.props.type}
className="form-control"
id={this.props.id}
onFocus={this.handleFocus.bind(null, true)}
onBlur={this.handleFocus.bind(null, false)}
onKeyUp={this.handleKeyUp} />
</div>
);
} else if (this.props.type === 'submit') {
formElement = (
<button type="submit"
ref="submitButton"
className="btn btn-primary">{this.props.label}</button>
);
}
return formElement;
}
});
您可以在 <Form id="login-form">
<FormElement id="email" label="Email Address" type="email" required={true} />
<FormElement id="password" label="Password" type="password" required={true} />
<FormElement id="login-button" label="Log In" type="submit" />
</Form>
中看到React.Children.forEach
循环,我正在尝试查看提交按钮是否存在,并默认禁用它,但我不知道如何操作该循环中的对象。 jQuery调用什么都不做。这也可能是完全错误的做法。
代码尚未完成(就验证而言)。我们的想法是,如果需要Form
,FormElement
和touched === true
,那么父filled === false
将以某种方式知道该状态并保持提交按钮被禁用。
答案 0 :(得分:1)
我认为你可能试图在表单元素中加入过多的逻辑,并且在使用React时,你不应该尝试触及DOM,因为你在循环中使用了一些jQuery操作。
我这样做的方式,表单会有一些与之关联的状态,即所有字段的内容。 render
会将这些值传递给FormElement
s,这会将它们传递给input
。 FormElement
会向委托给onChange
的{{1}}提供input
,onChange
将由Form
提供,disabled
将处理此更改并更新其状态。这为您提供了表单的基本功能。
由于表单现在知道当前填写的数据,因此可以直接推断是否应该启用提交按钮。然后,它可以将FormElement
属性传递给render
函数中的FormElement
,input
可以将其传递给<script src="https://fb.me/react-0.13.3.min.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<div id="application"></div>
<script type="text/jsx">
var Form = React.createClass({
getInitialState: function getInitialState() {
return {
firstName: "",
lastName: ""
};
},
render: function render() {
return <form>
<FormElement label="First name" value={this.state.firstName} onChange={this.firstNameChanged} />
<FormElement label="Last name" value={this.state.lastName} onChange={this.lastNameChanged} />
<SubmitButton enabled={!!this.state.firstName.trim() && !!this.state.lastName.trim()} />
</form>;
},
firstNameChanged: function(newFirstName) {
this.setState({firstName: newFirstName});
},
lastNameChanged: function(newLastName) {
this.setState({lastName: newLastName});
}
});
var FormElement = React.createClass({
render: function render() {
return <p><label>{this.props.label}: <input type="text" value={this.value} onChange={this.changed} /></label></p>;
},
changed: function changed(e) {
if(this.props.onChange) {
this.props.onChange(e.target.value);
}
}
});
var SubmitButton = React.createClass({
render: function render() {
return <p><input type="submit" value="Submit" disabled={!this.props.enabled} /></p>;
}
});
React.render(<Form />, document.getElementById("application"));
</script>
。
简化示例:
Form
在评论中,您说您希望LoginForm
不知道任何特定字段。好吧,你也可以这样做:将数据存储在你的FormElement
或者你拥有的内容中,然后再让数据流下来并提供一种向父母提供回调的方法,例如: (这里放弃<script src="https://fb.me/react-0.13.3.min.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<div id="application"></div>
<script type="text/jsx">
var NameForm = React.createClass({
getInitialState: function getInitialState() {
return {
firstName: "",
lastName: ""
};
},
render: function render() {
return <Form fields={this.getFields()} onFieldChange={this.fieldChanged} canSubmit={this.canSubmit()} />;
},
getFields: function getFields() {
return [
{id: "firstName", label: "First name", value: this.state.firstName},
{id: "lastName", label: "Last name", value: this.state.lastName}
];
},
fieldChanged: function fieldChanged(which, newValue) {
if(which === "firstName") {
this.setState({firstName: newValue});
}else if(which === "lastName") {
this.setState({lastName: newValue});
}
},
canSubmit: function canSubmit() {
return !!this.state.firstName && !!this.state.lastName;
}
});
var Form = React.createClass({
render: function render() {
return <form>
{this.props.fields.map(function(field) {
return <p key={field.id}><label>{field.label}: <input type="text" value={field.value} onChange={this.fieldChanged.bind(null, field.id)} /></label></p>;
}.bind(this))}
<input type="submit" value="Submit" disabled={!this.props.canSubmit} />
</form>;
},
fieldChanged: function(which, e) {
if(this.props.onFieldChange) {
this.props.onFieldChange(which, e.target.value);
}
}
});
React.render(<NameForm />, document.getElementById("application"));
</script>
,因为这些片段越来越长,我不想贬低这一点):
import turtle
centerX = float(input("Enter the center x cordinates of the rectangle: "))
centerY = float(input("Enter the center y cordinates of the rectangle: "))
width = float(input("enter, width: "))
height = float(input("enter, height: "))
turtle.showturtle()
turtle.penup()
turtle.goto(centerX,centerY)
turtle.pendown()
turtle.goto(-width/2,centerY)
turtle.goto(-width/2,height/2)
turtle.goto(width,height/2)
turtle.goto(width,-height)
turtle.goto(-width,-height)
turtle.goto(-width,height/2)
答案 1 :(得分:0)
当谈到React元素之间的通信时,我终于来到Flux,因为它是为此目的而设计的。基本上,您创建一个包含验证用户输入的所有逻辑的单个状态机(存储),任何可能还有配置所需内容的方法/需要哪些字段。 Form
的每个领域/孩子都在商店注册,告诉它“嘿,我在这里,我提供这个/那个信息”。最后在提交时,商店检查所有已注册/必填字段是否报告了有效的用户输入