react教程(一)JSX语法、组件概念、生命周期介绍

JSX

React中,推出了一种新的语法取名为JSX,它给了JS中写HTML标签的能力,不需要加引号。JSX的语法看起来是一种模板,然而它在编译以后,会转成JS语法,只是书写过程中的语法糖。
JSX的解析器会帮我们读取这种语法并加以处理。
下面是一个简单的例子。

const element = <h1 className="greeting">Hello, world!</h1>;

其实相当于如下的代码:

const element = React.createElement({
  'h1',
  {className: 'greeting'},
  'Hello, world!',
  'Xxx'
})

第一个参数是类型,可以是HTML标签,也可以是React组件;第二个参数是props对象;第三个以后参数是children,会按照传入顺序依次排列。
当然第三个参数也可以传入数组,如果第三个参数传入数组,则后面再传入其他子节点,就会报错。
JSX提供了一种HTML和JS混合编写的能力。在需要使用JS表达式的地方,用一组花括号包裹起来即可:

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1 className="test">
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('app')
);

由于class在js中关键字,所以使用className去替代。
上面说到了JSX其实是语法糖,所以如果要循环嵌入列表,可以直接将列表传进来:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('app')
);

在控制台中会看到这样的报错:

warning.js:33 Warning: Each child in an array or iterator should have a unique "key" prop.

这是由于react使用virtual
dom来渲染真实节点,在列表渲染时,如果每个item没有对应的key,react处理起增删改时就会很慢,所以,渲染列表时,最好给每一个item增加一个唯一的key。

const listItems = numbers.map((number, index) =>
  <li key={index}>{number}</li>
);

学习资料

react官方首页
https://facebook.github.io/react/
react中文
http://reactjs.cn/react/index.html
React Gitbook 翻译
https://hulufei.gitbooks.io/react-tutorial/content/introduction.html
react中文导航
http://nav.react-china.org/
jsx首页
https://facebook.github.io/jsx/
react教程
http://www.runoob.com/react/react-tutorial.html
https://github.com/facebook/react/wiki/Sites-Using-React

什么是React?
React 是一个用于构建用户界面的 JAVASCRIPT 库。
React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013
年 5 月开源。
React
拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
既可以开发浏览器应用,又可以开发移动应用

React 特点
1.声明式设计 −React采用声明范式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX
,但我们建议使用它。
5.组件 − 通过 React
构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React
实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

什么是JSX?
React 使用 JSX(JavaScript XML) 来替代常规的 JavaScript。JSX
是一个看起来很像 XML 的 JavaScript 语法扩展。我们不需要一定使用
JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。

  • 使用 JSX 编写模板更加简单快速。

直接在javaScript里面写xml的语法,使结构更加的清晰。基于ES6的语法。

State(状态)
React 把组件看成是一个状态机(State
Machines)。通过与用户的交互,实现不同状态,然后渲染
UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state
重新渲染用户界面(不要操作 DOM)。
不需要直接操作DOM,而是通过修改state,自动更新界面

Props(属性)
state 和 props 主要的区别在于 props 是不可变的,而 state
可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state
来更新和修改数据。 而子组件只能通过 props 来传递数据。
可以通过 getDefaultProps() 方法为 props 设置默认值

React组件生命周期

实例化

首次实例化

  • getDefaultProps
  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

实例化完成后的更新

  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

存在期
组件已存在时的状态改变

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

销毁&清理期

  • componentWillUnmount

生命周期共提供了10个不同的API。

1.getDefaultProps
作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享。

2.getInitialState
作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props。

3.componentWillMount
在完成首次渲染之前调用,此时仍可以修改组件的state。

4.render
必选的方法,创建虚拟DOM,该方法具有特殊的规则:

  • 只能通过this.props和this.state访问数据
  • 可以返回null、false或任何React组件
  • 只能出现一个顶级组件(不能返回数组)
  • 不能改变组件的状态
  • 不能修改DOM的输出

5.componentDidMount
真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。
在服务端中,该方法不会被调用。

6.componentWillReceiveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。
componentWillReceiveProps: function(nextProps) {
if (nextProps.bool) {
this.setState({
bool: true
});
}
}

7.shouldComponentUpdate
组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。
在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用

8.componentWillUpdate
接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。

9.componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。

10.componentWillUnmount
组件被移除之前被调用,可以用于做一些清理工作,在componentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。

组件

React中最重要的概念就是组件。

Conceptually, components are like JavaScript functions. They accept
arbitrary inputs (called “props”) and return React elements describing
what should appear on the screen.

组件可以看做是一个函数,指定了输入(props),就会给出输出(一个React元素)。
创建组件有两种方法:
1.函数

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

2.es6的类

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

第二种方法创建的组件,可以拥有内部状态(state)和生命周期函数。
如果只是展示信息,没有复杂的操作,可以选择第一种函数方法。如果组件比较复杂,并且需要在不同的时期做初始化或者销毁等工作,就要采用第二种ES6类方法。

状态(State)

State类似于props,但它是组件私有的并且完全由组件控制。
下面我们结合一个Clock类来演示State的概念。

import React, {Component} from 'react';

export default class Clock extends Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

在这个组件里,Clock就拥有了自己的状态,而不是从外界发生传入。接下来我们增加一个定时器的功能,来引入生命周期。

import React, {Component} from 'react';

export default class Clock extends Component {
  ...

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID)
  }

  tick () {
    this.setState({date: new Date()})
  }
  ...
}

注意:在React中,调用setState方法去修改state,会触发View视图层的修改,直接设置state就不会触发state的修改。
上面引入了两个生命周期方法:componentDidMount , componentWillUnmount

componentDidMount 会在组件挂载到DOM节点上之后触发,而
componentWillUnmount 会在组件从节点上移除以后触发。
React还有很多生命周期方法,下面做一个详细的说明。

生命周期

在React中,一个组件可能会经历创建、挂载、更新、卸载、销毁这些事件,React为我们提供了钩子函数来在这些事件触发时进行操作。
他的生命周期可以分为三大部分:
创建更新销毁
创建组件并将其插入DOM时,下面的方法会依次触发

constructor()
static getDerivedStateFromProps()
render()
componentDidMount()

更新时,将会触发

static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()

卸载时,触发

componentWillUnmount()

为了更加直观的查看生命周期方法,可以参考这张图:
图片 1
图片来源:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
Render阶段,把一些state和props计算执行。
Commit阶段就是把React组件插入到真实DOM节点上,这个时候可以使用DOM。
而Pre-commit阶段就是在插入真实DOM之前,这个阶段可以读取DOM。

创建时

constructor

1.用来初始化props和state。
2.是唯一可以直接修改state的地方。

getDerivedStateFromProps

1.当state需要从props初始化时使用
2.尽量不要使用:因为维护两者的一致会增加复杂度
3.每次render前都会被调用
4.典型场景:表单控件获取默认值

render

不能缺少的,它实际上决定了组件到底要渲染成什么样子。

发表评论

电子邮件地址不会被公开。 必填项已用*标注