参照React官方文档:https://reactjs.org/docs/
React采用组件化的思想构建UI,并提供jsx
语法创建元素,可以通过两种方式创建React组件:
//函数
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// ES6 class
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
ReactDOM.render(
<Welcome/>,
document.getElementById('root')
);
组件可以进行嵌套。
看一个计时的例子:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {secondsElapsed: 0};
}
tick(){
this.setState({
secondsElapsed: this.state.secondsElapsed + 1
})
}
componentDidMount(){
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount(){
clearInterval(this.interval);
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.secondsElapsed}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
- 调用
ReactDOM.render()
方法,渲染Clock
组件,执行其构造函数,初始化state
- 组件所有元素渲染完毕,执行
componentDidMount()
生命周期钩子函数,设定计时器 - 浏览器每秒执行一次
tick()
,在其内部改变state
,状态发生改变,构建新的虚拟DOM,与旧的虚拟DOM进行对比,使用diff算法找到变化的地方,应用到真实DOM - 组件从DOM中移除时,执行
componentWillUnmount()
钩子函数,在这里移除定时器
所有生命周期:https://reactjs.org/docs/react-component.html
组件的状态可以通过props
传递给子组件来改变下层组件:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {secondsElapsed: 0};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.secondsElapsed}.</h2>
<Child number={this.state.secondsElapsed}/>
</div>
);
}
}
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>It is {this.props.number}.</h2>
</div>
);
}
}
即组件的状态只能向下传递,该组件又可以接受来自它的父组件的props
,这样一层层地自顶向下传递。
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的DOM树,插到文档当中
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
- 把上面所记录的差异应用到第一步所构建的真正的DOM树上,视图就更新了
网上看到的一篇文章,讲的preact
的虚拟DOM实现,和React原理差不多:
参照原文:https://medium.com/@rajaraodv/the-inner-workings-of-virtual-dom-666ee7ad47cf