在使用 React.js 几天后,我编写了大部分表单,如下所示(如 official tutorial 中所示):
React.createClass({
handleSubmit: function (event) {
event.preventDefault();
var value = React.findDOMNode(this.refs.text).value;
// do something with the value
},
render: function () {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" ref="text" defaultValue="foo" />
<input type="submit" value="Save"/>
</form>
);
}
}
但是,我最近发现了这种方法的一个弱点,即我无法编写丰富的表单组件以用于由此类组件构建的表单,例如:
var RichInput = React.createClass({
render: function() {
return (
<div className="someStyle">
<input type="text" ref="text" defaultValue="foo" />
</div>
);
}
}
React.createClass({
handleSubmit: function (event) {
event.preventDefault();
var value = React.findDOMNode(this.refs.text).value;
// do something with the value
},
render: function () {
return (
<form onSubmit={this.handleSubmit}>
<RichInput />
<input type="submit" value="Save"/>
</form>
);
}
}
现在我想知道。查看可用资源后,我发现可以使用以下方法来克服此限制:
var RichInput = React.createClass({
render: function() {
return (
<div className="someStyle">
<input type="text" value="foo" onChange={this.props.callback} />
</div>
);
}
}
React.createClass({
handleSubmit: function (event) {
event.preventDefault();
var value = this.state.text
// do something with the value
},
getInitialState() {
return {text: 'foo'};
}
updateText: function(value) {
this.setState({text: value});
}
render: function () {
return (
<form onSubmit={this.handleSubmit}>
<RichInput callback={this.updateText} />
<input type="submit" value="Save"/>
</form>
);
}
}
这是编写模块化表单组件的规范解决方案吗?我想知道这对我来说确实是一个很大的开销。我需要编写额外的函数并且我需要使组件状态完整,这让我有点远离适应这个解决方案。另外,我想知道性能,因为我真的不需要在每次更改时更新值,而只在(并且在提交表单的情况下)更新值。
我发现的一种可能性是使用:
React.findDOMNode(this.refs.rich.refs.text);
假设 RichInput
定义了 ref="rich"
。但话又说回来,React 的文档说 refs 不应被视为公共(public) API,不应在组件外部访问。
最佳答案
这就是我构建抽象 Input
组件的方式。我将它用于各种目的(每当我需要用户输入某些内容并且我想稍后处理该操作时)(带有一些 Bootstrap 样式的 ES6/7 示例):
import React, { PropTypes, Component } from 'react';
export default class Input extends Component {
static propTypes = {
placeholder: PropTypes.string,
buttonText: PropTypes.string,
onButtonClick: PropTypes.func
}
constructor() {
super();
this._handleClick = this._handleClick.bind(this);
this._handleKeyUp = this._handleKeyUp.bind(this);
}
render() {
return (
<div className='Input'>
<div className='input-group'>
<input type='text' className='form-control' placeholder={this.props.placeholder}
ref='inputBox' onKeyUp={this._handleKeyUp}
/>
<span className='input-group-btn'>
<form onSubmit={this._handleClick}>
<button className='btn btn-success' type='submit'>{this.props.buttonText}</button>
</form>
</span>
</div>
</div>
);
}
_handleClick(e) {
e.preventDefault();
let value = this.refs.inputBox.getDOMNode().value;
this.props.onButtonClick(value);
value = null;
}
_handleKeyUp(e) {
e.preventDefault();
if (e.keyCode === 13) {
this._handleClick(e);
}
}
}
然后在 Parent
组件中,您可以像这样初始化它:
<Input placeholder='Enter something'
buttonText='Submit'
onButtonClick={this._handleButtonClick}
/>
并处理 _handleButtonClick
:
_handleMakeSearch(text) {
console.log(text);
}
关于javascript - 创建丰富的表单组件以向父组件公开值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31161277/