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 来定义组件:
- 须继承React.Component
- 在内部必须定义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):组件判断是否重新渲染时调用