Version:15.01
React是一个构建用户界面的JS库。
- 仅仅用来做UI
许多人用React做MVC中的View。由于React对View之外的技术栈不做限制,要在一个已有的项目中使用一些小特性是非常容易的。 - 虚拟DOM
React抽象了DOM,事编程模型更加简单,性能更好。React也可以使用Node在服务端渲染,同时它也可以使用React Native支持原生应用。 - 数据流
React实现单向响应式数据流,这样就减少了模板并且相对于传统的数据绑定更加容易推理。
**一个简单的组件
**
React组建实现了一个render()方法,它接受数据输入,返回要显示的内容。这个例子使用名为JSX的类XML语法。传入组建的输入数据,render()可以通过this.props获取。
使用React时,JSX是可选的而非必须。通过点击“Compiled JS”可以查看JSX编译器产生的原生JS代码。
JSX代码:
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
ReactDOM.render(<HelloMessage name="John" />, mountNode);
对应JS代码:
"use strict";
var HelloMessage = React.createClass({
displayName: "HelloMessage",
render: function render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
});
ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);
**一个状态组件
**
除了接受输入数据(通过this.props),组件也可以维持一个内部状态数据(通过this.state)。当一个组件的状态数据改变时,渲染的标签也会通过重新激发render()被更新。
JSX代码:
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>
);
}
});
ReactDOM.render(<Timer />, mountNode);
对应JS代码:
"use strict";
var Timer = React.createClass({
displayName: "Timer",
getInitialState: function getInitialState() {
return { secondsElapsed: 0 };
},
tick: function tick() {
this.setState({ secondsElapsed: this.state.secondsElapsed + 1 });
},
componentDidMount: function componentDidMount() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function componentWillUnmount() {
clearInterval(this.interval);
},
render: function render() {
return React.createElement(
"div",
null,
"Seconds Elapsed: ",
this.state.secondsElapsed
);
}
});
ReactDOM.render(React.createElement(Timer, null), mountNode);
**一个应用(Todo)
**
使用props和states,我们可以整合一个小的Todo应用。这个例子使用state跟踪当前项目列表和用户输入文本。虽然事件处理器看似在行内渲染,但是它们会被收集并使用事件代理实现。
JSX代码:
var TodoList = React.createClass({
render: function() {
var createItem = function(item) {
return <li key={item.id}>{item.text}</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([{text: this.state.text, id: Date.now()}]);
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>
);
}
});
ReactDOM.render(<TodoApp />, mountNode);
对应JS代码:
'use strict';
var TodoList = React.createClass({
displayName: 'TodoList',
render: function render() {
var createItem = function createItem(item) {
return React.createElement(
'li',
{ key: item.id },
item.text
);
};
return React.createElement(
'ul',
null,
this.props.items.map(createItem)
);
}
});
var TodoApp = React.createClass({
displayName: 'TodoApp',
getInitialState: function getInitialState() {
return { items: [], text: '' };
},
onChange: function onChange(e) {
this.setState({ text: e.target.value });
},
handleSubmit: function handleSubmit(e) {
e.preventDefault();
var nextItems = this.state.items.concat([{ text: this.state.text, id: Date.now() }]);
var nextText = '';
this.setState({ items: nextItems, text: nextText });
},
render: function render() {
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)
)
)
);
}
});
ReactDOM.render(React.createElement(TodoApp, null), mountNode);
一个使用外部插件的组件
React非常灵活,提供了和其他库和框架交互的钩子。本例使用marked(一个外部Markdown库)来实时转换文本域中的内容。
JSX代码:
var MarkdownEditor = React.createClass({
getInitialState: function() {
return {value: 'Type some *markdown* here!'};
},
handleChange: function() {
this.setState({value: this.refs.textarea.value});
},
rawMarkup: function() {
return { __html: marked(this.state.value, {sanitize: true}) };
},
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={this.rawMarkup()}
/>
</div>
);
}
});
ReactDOM.render(<MarkdownEditor />, mountNode);
对应JS代码:
"use strict";
var MarkdownEditor = React.createClass({
displayName: "MarkdownEditor",
getInitialState: function getInitialState() {
return { value: 'Type some *markdown* here!' };
},
handleChange: function handleChange() {
this.setState({ value: this.refs.textarea.value });
},
rawMarkup: function rawMarkup() {
return { __html: marked(this.state.value, { sanitize: true }) };
},
render: function render() {
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: this.rawMarkup()
})
);
}
});
ReactDOM.render(React.createElement(MarkdownEditor, null), mountNode);
网友评论