react相关文档的阅读
This commit is contained in:
191
react/react.md
Normal file
191
react/react.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# React
|
||||||
|
## 概览
|
||||||
|
React是一个声明式,用于构建用户界面的JavaScript库。React可以将一些简短、独立的代码片段组合成复杂的ui界面,**独立的代码片段在React中被称之为组件**。
|
||||||
|
## React.Component组件
|
||||||
|
```js
|
||||||
|
class ShoppingList extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="shopping-list">
|
||||||
|
<h1>Shopping List for {this.props.name}</h1>
|
||||||
|
<ul>
|
||||||
|
<li>Instagram</li>
|
||||||
|
<li>WhatsApp</li>
|
||||||
|
<li>Oculus</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用法示例: <ShoppingList name="Mark" />
|
||||||
|
```
|
||||||
|
可以通过组件来告诉React需要在屏幕上显示的内容,当数据发生改变时,**React会高效的更新内容并重新渲染组件**。
|
||||||
|
以上,ShoppingList声明了一个React组件类型。React组件类型会接受一些组件参数,该参数称之为`props`,组件还会通过render方法返回显示在屏幕上的视图层次结构。
|
||||||
|
render方法的返回值将会描述希望在屏幕上看到的内容。render返回值是一个React元素,是对渲染元素的轻量级描述。`jsx`语法支持更简单的书写这些结构,语法\</div\>会被编译为如下内容:
|
||||||
|
```js
|
||||||
|
return React.createElement('div', {className: 'shopping-list'},
|
||||||
|
React.createElement('h1', /* ... h1 children ... */),
|
||||||
|
React.createElement('ul', /* ... ul children ... */)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
在jsx中,可以在html元素中使用js表达式,只需要用大括号将js表达式括起来。
|
||||||
|
```js
|
||||||
|
<h1>Shopping List for {this.props.name}</h1>
|
||||||
|
```
|
||||||
|
上述示例中的ShoppingList只渲染了一些内置的DOM组件,如`div`,`li`等,但是也可以组合和渲染自定义的React组件。例如,可以通过`<ShoppingList/>`来表示整个购物清单组件。
|
||||||
|
> 每个组件都是封装好的,并可以单独运行,如此可以通过组合组件来构建复杂代码
|
||||||
|
|
||||||
|
## 组件响应事件及状态
|
||||||
|
### 事件处理函数
|
||||||
|
如果想要为组件指定事件处理函数,可以通过如下方式:
|
||||||
|
```js
|
||||||
|
class Square extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button className="square" onClick={function() { alert('click'); }}>
|
||||||
|
{this.props.value}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 组件状态
|
||||||
|
可以通过在组件构造函数中初始化`this.state`属性来存储组件状态,this.state应被视作组件的私有属性。
|
||||||
|
示例如下:
|
||||||
|
```js
|
||||||
|
class Square extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
value: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button className="square" onClick={() => alert('click')}>
|
||||||
|
{this.props.value}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
可以通过如下代码来修改和渲染React组件中的state属性:
|
||||||
|
```js
|
||||||
|
class Square extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
value: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="square"
|
||||||
|
onClick={() => this.setState({value: 'X'})}
|
||||||
|
>
|
||||||
|
{this.state.value}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
> ### setState
|
||||||
|
> 每次在组件内调用setState方法时,React都会自动更新其子组件。
|
||||||
|
|
||||||
|
### 组件状态提升
|
||||||
|
如果需要同时获取多个子组件的数据,或者多个组件之间需要通信,此时,可以将子组件的state数据提升至父组件中进行存储。
|
||||||
|
父子组件之间传递数据和处理函数的示例如下:
|
||||||
|
```js
|
||||||
|
// parent component,
|
||||||
|
// pass `value`,`onclick` props to child component
|
||||||
|
class Board extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
squares: Array(9).fill(null),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick(i) {
|
||||||
|
const squares = this.state.squares.slice();
|
||||||
|
squares[i] = 'X';
|
||||||
|
this.setState({squares: squares});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSquare(i) {
|
||||||
|
return (
|
||||||
|
<Square
|
||||||
|
value={this.state.squares[i]}
|
||||||
|
onClick={() => this.handleClick(i)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const status = 'Next player: X';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="status">{status}</div>
|
||||||
|
<div className="board-row">
|
||||||
|
{this.renderSquare(0)}
|
||||||
|
{this.renderSquare(1)}
|
||||||
|
{this.renderSquare(2)}
|
||||||
|
</div>
|
||||||
|
<div className="board-row">
|
||||||
|
{this.renderSquare(3)}
|
||||||
|
{this.renderSquare(4)}
|
||||||
|
{this.renderSquare(5)}
|
||||||
|
</div>
|
||||||
|
<div className="board-row">
|
||||||
|
{this.renderSquare(6)}
|
||||||
|
{this.renderSquare(7)}
|
||||||
|
{this.renderSquare(8)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// child component
|
||||||
|
class Square extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="square"
|
||||||
|
onClick={() => this.props.onClick()}
|
||||||
|
>
|
||||||
|
{this.props.value}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### React不可变性
|
||||||
|
相比于直接修改原有数据的属性,直接用新对象替换旧的数据对象是更推荐的做法,其有如下优点:
|
||||||
|
- 如果需要查看属性的历史值或实现撤回功能,那么不可变数据将会令实现相当简单,只要存储历史state对象就可以
|
||||||
|
- 如果使用不可变对象,查看数据是否更改会容易很多,只需将旧对象地址和新对象地址进行比较即可,无需遍历对象结构并比较属性值
|
||||||
|
- 不可变对象可以轻易的发现数据对象是否发生改变,从而确定React是否应该重新渲染
|
||||||
|
|
||||||
|
## 函数组件
|
||||||
|
如果组件中并不包含state状态,且组件只包含render一个方法,可以通过函数来实现其组件,而无需继承React.Component类。
|
||||||
|
通过函数组件替换React.Component组件的示例如下:
|
||||||
|
```js
|
||||||
|
function Square(props) {
|
||||||
|
return (
|
||||||
|
<button className="square" onClick={props.onClick}>
|
||||||
|
{props.value}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## React list
|
||||||
|
在React中使用列表时,需要为列表项指定一个key,以区分该列表项和其他兄弟列表项。
|
||||||
|
`key`是React中一个特殊的保留属性,当React元素被创建时,React会获取key属性并且将其存储到返回的元素中。元素的`key`属性并无法通过`this.props.key`形式来获取,React会通过`key`自动判断哪些组件需要被更新,但是组件无法访问它的`key`。
|
||||||
|
> 组件的key并不需要在全局保证唯一,只需要在当前同一级元素之中key保持唯一即可
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user