React学习笔记(一)

251 阅读5分钟

1.定义

首先React的官方定义是用于构建用户界面的 JavaScript 库。

它是一个声明式、高效且灵活的用于构建用户界面的 JavaScript 库。 使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作 “组件(component)”

基本语法:

  • ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
  • React.createElement() 创建元素(虚拟dom模拟真实dom进行对比差异,然后渲染), react核心库提供各种api操作dom
  • React.Component ES6语法,开发中经常使用extents继承React.Component

2. JSX

HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这种写法是JSX语法 。

JSX 是JS的语法扩展。JSX中可以直接插入JavaScript 表达式,用{ }括起来。表达式是会返回一个值的代码单元,比如变量,二三维运算,函数执行返回结果。表达式都可以用{}扩起来写进JSX里。

const name = "Jesse"
const element1 = <div> Hi, {name} </div>

const age = 17
const element2 = <div> a {age > 18 ? "Adult":"Teenager"}</div>

const element3 = <div>{f1()}</div>

JSX 也是一个表达式。在Babel编译之后,JSX 表达式会被转为普通 JavaScript 函数调用,并且对其取值后得到 JavaScript 对象。Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。

比如:以下两种表达等效。

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

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

JSX简化了代码,提升效率;页面或组件的渲染逻辑应该与其他UI逻辑放在一起,HTML和JS往往会把UI逻辑和渲染逻辑分开,JSX将两件事情合在了一起。

3. React元素(element)

元素是React最小单元,下面提到的组件(component)是由元素构成。 想要将一个 React 元素渲染到根 DOM 节点中,要把它们一起传入 ReactDOM.render()

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

每一个 React 元素事实上都是一个 JavaScript 对象,可以把它当保存在变量中或者作为参数(props)传递。

React元素(element)不可变(immutable).

4. React组件(Component)

定义

组件可以将UI拆分为独立(independent)可复用(reusable)的片段,并进行单独的构思(thing about each piece in isolation)。

React组件由React元素组成。

函数式组件
const element = <Welcome name="Jesse" age={17}/>;

function Welcome(props){
	return <h1> Hi, {props.name}, your age is {props.age}</h1>;
}

该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,它本质上就是 JavaScript 函数。

类组件

使用 ES6 的 class 来定义组件:

  1. 须继承React.Component
  2. 在内部必须定义render方法,render返回该组件UI的React元素
const element = <Welcome name="Jesse" age={17}/>;

class Welcome extends React.Component {
	constructor(props) {
    	super(props);
    	this.state = {date: new Date()};  }

    render(){
    	return (
        <div>
        <h1>Hi, {this.props.name}, your age is {this.props.age}.</h1>;
        <h2>It is {this.state.date.toLocaleTimeString()now}.</h2>
        </div>
        )
    }
}

组件类的第一个字母必须大写,否则会报错,比如Welcome不能写成welcome。

React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签,而 <Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome。

在 JavaScript class 中,每次定义其子类的构造函数时,都需要调用 super 方法。因此,在所有含有构造函数的的 React 组件中,构造函数必须以 super(props) 开头。

Class 组件应该始终使用 props 参数来调用父类的构造函数。

另外,组件类只能包含一个顶层标签,否则也会报错。Render()最外层标签数目只能是1个,不过可以用Fragment占位,包裹多个标签。

Fragments 可以聚合一个子元素列表,并且不在DOM中增加额外节点。

ReactDOM.render(
  <TodoList />,
 //<div>TodoList</div> 这样有两个标签就会报错

   document.getElementById('root')
);

Fragments 看起来像空的 JSX 标签:

ReactDOM.render(
	<>
  <TodoList />,
 <div>TodoList</div> //这样就不会报错了
	</>
   document.getElementById('root')
);

5. State & props

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。State是一个组件的UI数据模型,是组件渲染时的数据依据。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

组件接收的参数叫做props(properties)。

Props对于使用它的组件来说,是只读的,要想修改Props,只能通过该组件的父组件修改

修改state

使用setState()

this.setState({comment: 'Hello'});

State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。

在 React 应用中,数据通过 props 的传递,从父组件流向子组件,

State 的更新

调用setState后,setState会把要修改的状态放入一个队列中(组件的state并不会立即改变);

之后React 会优化真正的执行时机,来优化性能,所以优化过程中有可能会将多个 setState 的状态修改合并为一次状态修改,因而state更新可能是异步的。

6. 生命周期(lifycycle)

组件的生命周期分成三个状态:

    Mounting:已插入真实 DOM
    Updating:正在被重新渲染
    Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

    componentWillMount()
    componentDidMount()
    componentWillUpdate(object nextProps, object nextState)
    componentDidUpdate(object prevProps, object prevState)
    componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

    componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
    shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用