export default class MyComponent extends React.Component { onSubmit(e) { e.preventDefault(); var title = this.title; console.log(title); } render(){ return ( ... <form className="form-horizontal"> ... <input type="text" className="form-control" ref={(c) => this.title = c} name="title" /> ... </form> ... <button type="button" onClick={this.onSubmit} className="btn">Save</button> ... ); } };
控制台给我未定义 – 任何想法这个代码有什么问题?
反应15及以下
根据React文档和教程,正确地做事情.您正在编写一个基于两件事呈现的UI:
>组件的属性,由无论哪个父创建该组件的实例声明,该父实体可以在其整个生命周期中进行修改,以及
>组件自身的内部状态,它可以在其自身的生命周期中自行修改.
你没有做的是生成一个输入元素DOM节点,然后键入.您正在生成一个必须显示可操作的文本字符串的UI,并且操作会更改组件的状态,这可能会导致重新投递.国家永远是最终的权威,而不是DOM. DOM是一个事后的想法,它只是你正在使用的特定UI框架.
所以,要做好事情,你的组件有一个状态值,它通过输入字段显示,我们可以通过使UI元素将更改事件发回到组件中来进行更新:
var Component = React.createClass({ getInitialState: function() { return { inputValue: '' }; },render: function() { return ( //... <input value={this.state.inputValue} onChange={this.updateInputValue}/> //... ); },updateInputValue: function(evt) { this.setState({ inputValue: evt.target.value }); } });
您输入的输入元素,没有任何事情发生在您的输入元素,事件被截获并立即被杀死,React触发事件的updateInputValue函数.该功能要求React更新组件的状态,使其具有正确的值,然后React可以使用新的更新重新使用UI,因此只有UI显示您输入了一封信.所有这一切发生在几毫秒的时间内,所以看起来你正常打字,但这绝对不是发生了.
基于评论的增编
UI输入表示状态值(如果用户在中间关闭它的选项卡,并且选项卡被还原,会发生什么情况呢)如果所有这些值被还原,那么这个状态).这可能会使您感觉像一个大型表单需要几十甚至一百个输入表单,但是React是以可维护的方式建模您的UI:您没有100个独立的输入字段,您有一组相关的输入,因此您可以捕获每个组合在一个组件中,然后构建您的“主”表单作为组的集合.
MyForm: render: <PersonalData/> <AppPreferences/> <ThirdParty/> ...
这比一个巨大的单一形式组件更容易维护.将组分割成具有状态维护的组件,其中每个组件一次只负责跟踪几个输入字段.
你可能会觉得写出所有的代码是一件麻烦的事情,但这是一个虚假的储蓄:开发人员 – 谁不是你,包括未来的你,实际上受益匪浅,看到所有这些输入明确地联系在一起,因为它使代码路径更容易追踪.但是,您可以随时优化.例如,您可以编写状态链接器
MyComponent = React.createClass({ getInitialState() { return { firstName: this.props.firstName || "",lastName: this.props.lastName || "" ...: ... ... } },componentWillMount() { Object.keys(this.state).forEach(n => { let fn = n + 'Changed'; this[fn] = evt => { let update = {}; update[n] = evt.target.value; this.setState(update); }); }); },render: function() { return Object.keys(this.state).map(n => { <input key={n} type="text" value={this.state[n]} onChange={this[n + 'Changed']}/> }); } });
当然,这是有改进的版本,所以打了https://npmjs.com,搜索一个你最喜欢的React状态链接解决方案.开源大部分是关于发现别人已经完成的工作,而不是从头开始编写一切.
反应16(和15.5过渡)
从React 16(和从15.5开始软启动),不再支持createClass调用,需要使用类语法.这改变了两件事情:明显的类语法,也是createClass可以“免费”执行的thiscontext绑定,因此确保事情仍然工作,确保您使用“胖箭头”符号为上下文保留匿名函数onWhatever处理程序,例如我们在代码中使用的onChange:
class MyComponent extends React.Component { constructor(props) { super(props); this.state = { inputValue: '' }; } render: function() { return ( //... <input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/> //... ); },updateInputValue: function(evt) { this.setState({ inputValue: evt.target.value }); } });