实现一个简易版本的react,理清react的主干内容和重要知识点
jsx是一种语法糖,js能够写在html中。本质上是利用babel,转换为React.createElement()方法的调用。
这也是为什么每一个jsx文件中,虽然没有用到React
也需要引入。
const element = (
<div style={{ color: 'green', fontSize: '25px'}}>hello react jsx</div>
)
ReactDOM.render(
element,
document.getElementById('root')
)
jsx
语法糖原理:babel转换 -> React.createElement -> virtualDOM。需要自己实现React.createElement
方法。ReactDOM.render
: 由于html
结构是一个嵌套结构,所以在渲染vdom
的时候需要用到递归。在render
方法里创建dom
元素和为dom
添加对应的属性,并将dom
append
到对应的父节点里- 递归:
组件有两种方式:纯函数组件和用class定义的组件
class A extends Component {
render() {
<div style={{ color: 'green', fontSize: '25px'}}>hello component</div>
}
}
const B = () => {
return (
<div style={{ color: 'green', fontSize: '25px'}}>hello react jsx</div>
)
}
ReactDOM.render(
<A/>,
document.getElementById('root')
)
- 组件形式
<A/>
经过babel的编译后 ->React.createElement(A, null)
,这样意味着vdom
的nodeName
为一个函数,在render
的时候需要判断vdom.nodeName
如果为函数做相应的处理。
class A extends Component {
constructor(props) {
super(props)
this.state = {
count: 1
}
}
click() {
this.setState({
count: ++this.state.count
})
}
render() {
return (
<div>
<button onClick={this.click.bind(this)}>Click Me!</button>
<div>{this.props.name}:{this.state.count}</div>
</div>
)
}
}
ReactDOM.render(
<A name='luoqian'/>,
document.getElementById('root')
)
- 所有组件都继承
Component
构造函数,这个函数的原型上添加setState方法,当调用时重新渲染更新后的vdom
- 组件的props是如何传入组件的:在
render
的时候将vdom.attribute
传入new Vdom.nodeName(vdom.attribute)
,在组件的constructor
中将props
传入,调用super(props)
调用Component
构造函数,将props
添加到实例属性上。 ReactDOM.render
在每次热更新的时候需要清空当前渲染的dom。
将方法拆分到单独的文件中
Component.prototype.setState
的方法中传入的是新的state,将新的state和和旧的state组合后,调用component
的render
方法获得该组件的vdom
。再调用ReactDOM.render
方法重新渲染页面。
class A extends Component {
componentWillReceiveProps(props) {
console.log('componentWillReceiveProps')
}
render() {
return (
<div>{this.props.count}</div>
)
}
}
class B extends Component {
constructor(props) {
super(props)
this.state = {
count: 1
}
}
componentWillMount() {
console.log('componentWillMount')
}
componentDidMount() {
console.log('componentDidMount')
}
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate', nextProps, nextState)
return true
}
componentWillUpdate() {
console.log('componentWillUpdate')
}
componentDidUpdate() {
console.log('componentDidUpdate')
}
click() {
this.setState({
count: ++this.state.count
})
}
render() {
console.log('render')
return (
<div>
<button onClick={this.click.bind(this)}>Click Me!</button>
<A count={this.state.count} />
</div>
)
}
}
ReactDOM.render(
<B />,
document.getElementById('root')
)
首先你要十分清楚react的生命周期,执行生命周期函数,其实就是拿到定义的函数执行。那么如何拿到这些函数?第一个问题就是component
实例如何拿到
createComponent
函数用于获取这个实例。