一、简介
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 代码
```javascript
class 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(
```javascript
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 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>
<input
id="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(
```javascript
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 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>
<textarea
id="markdown-content"
onChange={this.handleChange}
defaultValue={this.state.value}
/>
<h3>Output</h3>
<div
className="content"
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
); } }
ReactDOM.render(
```javascript
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 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/