带状态的组件
除了可以通过this.props访问输入数据之外,组件还可以通过this.state来维持他的内部状态数据。当一个组件的状态数据改变时,组件将重新调用render()方法来重绘。
// JSX code
var Timer = React.createClass({
getInitialState: function() {
return {secondsElapsed: 0};
},
tick: function() {
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
render: function() {
return (
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
);
}
});
React.render(<Timer />, mountNode);
// compiled javascript code
var Timer = React.createClass({displayName: "Timer",
getInitialState: function() {
return {secondsElapsed: 0};
},
tick: function() {
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
render: function() {
return (
React.createElement("div", null, "Seconds Elapsed: ", this.state.secondsElapsed)
);
}
});
React.render(React.createElement(Timer, null), mountNode);
React应用
结合使用属性(props)和状态(state),可以构建一个基础的代办事项应用。这个例子中使用状态来跟踪事项列表和用户输入的新事项名称,即使事件处理程序看起来是内联的,他们仍将会通过代理被收集和实现。
// JSX code
var TodoList = React.createClass({
render: function() {
var createItem = function(itemText, index) {
return <li key={index + itemText}>{itemText}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [], text: ‘‘};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextText = ‘‘;
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<button>{‘Add #‘ + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});
React.render(<TodoApp />, mountNode);
// compiled javascript code
var TodoList = React.createClass({displayName: "TodoList",
render: function() {
var createItem = function(itemText, index) {
return React.createElement("li", {key: index + itemText}, itemText);
};
return React.createElement("ul", null, this.props.items.map(createItem));
}
});
var TodoApp = React.createClass({displayName: "TodoApp",
getInitialState: function() {
return {items: [], text: ‘‘};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextText = ‘‘;
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
React.createElement("div", null,
React.createElement("h3", null, "TODO"),
React.createElement(TodoList, {items: this.state.items}),
React.createElement("form", {onSubmit: this.handleSubmit},
React.createElement("input", {onChange: this.onChange, value: this.state.text}),
React.createElement("button", null, ‘Add #‘ + (this.state.items.length + 1))
)
)
);
}
});
React.render(React.createElement(TodoApp, null), mountNode);
组件可以使用第三方插件
React非常灵活,通过钩子允许与其他的库和框架对接。这个例子使用外部的Markdown库来实时转化文本域中的内容。
// JSX code
var MarkdownEditor = React.createClass({
getInitialState: function() {
return {value: ‘Type some *markdown* here!‘};
},
handleChange: function() {
this.setState({value: React.findDOMNode(this.refs.textarea).value});
},
render: function() {
return (
<div className="MarkdownEditor">
<h3>Input</h3>
<textarea onChange={this.handleChange} ref="textarea" defaultValue={this.state.value} />
<h3>Output</h3>
<div className="content" dangerouslySetInnerHTML={{
__html: marked(this.state.value, {sanitize: true})
}}/>
</div>
);
}
});
React.render(<MarkdownEditor />, mountNode);
// compiled javascript code
var MarkdownEditor = React.createClass({displayName: "MarkdownEditor",
getInitialState: function() {
return {value: ‘Type some *markdown* here!‘};
},
handleChange: function() {
this.setState({value: React.findDOMNode(this.refs.textarea).value});
},
render: function() {
return (
React.createElement("div", {className: "MarkdownEditor"},
React.createElement("h3", null, "Input"),
React.createElement("textarea", {
onChange: this.handleChange,
ref: "textarea",
defaultValue: this.state.value
}),
React.createElement("h3", null, "Output"),
React.createElement("div", {
className: "content",
dangerouslySetInnerHTML: {
__html: marked(this.state.value, {sanitize: true})
}
})
)
);
}
});
React.render(React.createElement(MarkdownEditor, null), mountNode);