一、简介
React 是一个用于构建用户界面的 JavaScript
二、三个特点
- 声明式
- 比较轻松创建交互 UI,为每个状态创建简洁的视图,数据变动时 React 会高效地去更新并渲染组件
- 代码更加可预测,更容易调试
- 组件化
- 组件有它们的状态,将它们组合能够构建复杂的 UI
- 组件使用 JavaScript 编写,所以很容易传递数据并保持状态与 DOM 分离
- 一次学习,跨平台编写
- 很容易引入 React 开发新功能
- 可以使用 Node 进行服务器渲染,可以使用 React Native 开发原生移动应用
三、看一看 JSX
1. 简单组件
- Rect 组件使用
render()方法接受数据并返回需要展示的内容 - 在示例中这种类似 XML 的写法被称为 JSX
- 被传入的数据可在组件中通过
this.props再render()访问 ```jsx class HelloMessage extends React.Component { render() { return (
); } }<div>Hello {this.props.name}</div>
ReactDOM.render(
对应的原生 JavaScript 代码```javascriptclass HelloMessage extends React.Component {render() {return React.createElement("div",null,"Hello ",this.props.name);}}ReactDOM.render(React.createElement(HelloMessage, { name: "Taylor" }),document.getElementById('hello-example'));
2. 有状态组件
- 组件还可以维护其内部的状态(通过
this.state访问) 当组件的状态数据改变时,组件会再次调用
render()方法更新对应的标记 ```jsx class Timer extends React.Component { constructor(props) { super(props); this.state = { seconds: 0 }; }tick() { this.setState(state => ({
seconds: state.seconds + 1
})); }
componentDidMount() { this.interval = setInterval(() => this.tick(), 1000); }
componentWillUnmount() { clearInterval(this.interval); }
render() { return (
<div>Seconds: {this.state.seconds}</div>
); } }
ReactDOM.render(
```javascriptclass Timer extends React.Component {constructor(props) {super(props);this.state = { seconds: 0 };}tick() {this.setState(state => ({seconds: state.seconds + 1}));}componentDidMount() {this.interval = setInterval(() => this.tick(), 1000);}componentWillUnmount() {clearInterval(this.interval);}render() {return React.createElement('div',null,'Seconds: ',this.state.seconds);}}ReactDOM.render(React.createElement(Timer, null),document.getElementById('timer-example'));
3. 应用
- 使用
props和state我们可以创建一个简易的 Todo 应用 - 示例中使用
state来保存现有的待办事项列表及用户的输入 尽管时间处理器看似被内联地渲染,但它们其实会被事件委托进行收集和调用 ```jsx class TodoApp extends React.Component { constructor(props) { super(props); this.state = { items: [], text: ‘’ }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); }
render() { return (
<div><h3>TODO</h3><TodoList items={this.state.items} /><form onSubmit={this.handleSubmit}><label htmlFor="new-todo">What needs to be done?</label><inputid="new-todo"onChange={this.handleChange}value={this.state.text}/><button>Add #{this.state.items.length + 1}</button></form></div>
); }
handleChange(e) { this.setState({ text: e.target.value }); }
handleSubmit(e) { e.preventDefault(); if (this.state.text.length === 0) {
return;
} const newItem = {
text: this.state.text,id: Date.now()
}; this.setState(state => ({
items: state.items.concat(newItem),text: ''
})); } }
class TodoList extends React.Component { render() { return (
-
{this.props.items.map(item => (
- {item.text} ))}
ReactDOM.render(
```javascriptclass TodoApp extends React.Component {constructor(props) {super(props);this.state = { items: [], text: '' };this.handleChange = this.handleChange.bind(this);this.handleSubmit = this.handleSubmit.bind(this);}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("label",{ htmlFor: "new-todo" },"What needs to be done?"),React.createElement("input", {id: "new-todo",onChange: this.handleChange,value: this.state.text}),React.createElement("button",null,"Add #",this.state.items.length + 1)));}handleChange(e) {this.setState({ text: e.target.value });}handleSubmit(e) {e.preventDefault();if (this.state.text.length === 0) {return;}const newItem = {text: this.state.text,id: Date.now()};this.setState(state => ({items: state.items.concat(newItem),text: ''}));}}class TodoList extends React.Component {render() {return React.createElement("ul",null,this.props.items.map(item => React.createElement("li",{ key: item.id },item.text)));}}ReactDOM.render(React.createElement(TodoApp, null),document.getElementById('todos-example'));
4. 在组件中使用外部插件
- React 结合其他框架或库一起使用
示例中使用一个名为 remarkable 的外部 Markdown 库,它可以实时转换
<textarea>里的内容 ```jsx class MarkdownEditor extends React.Component { constructor(props) { super(props); this.md = new Remarkable(); this.handleChange = this.handleChange.bind(this); this.state = { value: ‘Hello, world!’ }; }handleChange(e) { this.setState({ value: e.target.value }); }
getRawMarkup() { return { __html: this.md.render(this.state.value) }; }
render() { return (
<div className="MarkdownEditor"><h3>Input</h3><label htmlFor="markdown-content">Enter some markdown</label><textareaid="markdown-content"onChange={this.handleChange}defaultValue={this.state.value}/><h3>Output</h3><divclassName="content"dangerouslySetInnerHTML={this.getRawMarkup()}/></div>
); } }
ReactDOM.render(
```javascriptclass MarkdownEditor extends React.Component {constructor(props) {super(props);this.md = new Remarkable();this.handleChange = this.handleChange.bind(this);this.state = { value: 'Hello, **world**!' };}handleChange(e) {this.setState({ value: e.target.value });}getRawMarkup() {return { __html: this.md.render(this.state.value) };}render() {return React.createElement("div",{ className: "MarkdownEditor" },React.createElement("h3",null,"Input"),React.createElement("label",{ htmlFor: "markdown-content" },"Enter some markdown"),React.createElement("textarea", {id: "markdown-content",onChange: this.handleChange,defaultValue: this.state.value}),React.createElement("h3",null,"Output"),React.createElement("div", {className: "content",dangerouslySetInnerHTML: this.getRawMarkup()}));}}ReactDOM.render(React.createElement(MarkdownEditor, null), document.getElementById('markdown-example'));
四、参考链接
React 简介:https://reactjs.org/
