类组件和函数组件
Element vs Component
const div = React.createElement("div")//这是一个React元素
const Div =()=>React.createElement("div")//这是React一个组件React两种组件
- 函数组件
function Welcome(props) {
return <h1>Hello,{props.name}</h1>;//读取props
}
使用方法<Welcome name="leehome"/>- 类组件
class Welcome extends React.Component {
constructor() {
super();
}
render() {
return <h1>Hello,{this.props.name}</h1>;//读取props }}
使用方法:<Welcome name="leehome"/>tips
<div/>会被翻译成React.createElement("div"),
<Welcome/>翻译为React.createElement(Welcome)
具体可以用babel online 直接翻译查看
React.createElement的逻辑
- 如果传入一个字符串"div",则会创建一个div
- 如果传入一个函数,则会调用该函数,获取其返回值
- 如果传入一个类,则会在类前面加个new,获取一个组件对象,然后调用对象的render方法,获取其返回值
如何使用props和state
添加props
<Welcome name="leehome"/>类组件直接读取属性: this.props.name
函数组件直接读取参数:props.name
添加state
类组件用this.state读,this.setState写(setState尽量用函数形式)
this.setState ({n:this.state.n+1})
//this.setState(state=>({n:state.n+1}))函数组件用useState返回数组,第一项读,第二项写(写尽量用函数形式)
setN(n+1)
//setN(x=>x+1)类组件注意事项
this.state.n+=1 改变了n,但是UI不是自动更新而已,调用setState才会触发UI更新(异步更新)。
函数组件注意事项
- 跟类组件类似的地方
也要通过setX(新值)来更新UI
- 跟类组件不同的地方
没有this,一律用参数和变量
两种编程模式
Vue的编程模型:一个对象对应一个虚拟DOM,当对象的属性改变时,把属性相关的DOM节点全部更新(注:Vue为了其他考量,也引入了虚拟DOM和DOM diff,下图只是简化)
React的编程模型:一个对象,对应一个虚拟DOM,另一个对象,对应另一个虚拟DOM,对比两个虚拟DOM,找不同最后局部更新DOM。

复杂state
如果state里面不止有n:
- 类组件里面有n和m
class Son extends React.Component {
constructor() {
super();
this.state = {
n: 0,
m: 0
};
}
addN() {
this.setState({ n: this.state.n + 1 });
// m 会被覆盖为 undefined 吗?
}
addM() {
this.setState({ m: this.state.m + 1 });
// n 会被覆盖为 undefined 吗?
}
render() {
return (
<div className="Son">
儿子 n: {this.state.n}
<button onClick={() => this.addN()}>n+1</button>
m: {this.state.m}
<button onClick={() => this.addM()}>m+1</button>
<Grandson />
</div>
);
}
}类组件的setState会自动合并第一层属性,但不会合并第二层属性,我们可以Object.assign或者...操作符:
class Son extends React.Component {
constructor() {
super();
this.state = {
n: 0,
m: 0,
user: {
name: "frank",
age: 18
}
};
}
addN() {
this.setState({ n: this.state.n + 1 });
// m 会被覆盖为 undefined 吗?
}
addM() {
this.setState({ m: this.state.m + 1 });
// n 会被覆盖为 undefined 吗?
}
changeUser() {
this.setState({
// m 和 n 不会被置空
user: {
...this.state.user, // 复制之前的所有属性
name: "jack"
}
});
}- 函数组件里面和n和m
函数组件的setX则完全不会帮你合并,要合并可以用...操作符。
事件绑定
类函数的事件绑定(最好用)
class Son extends React.Component{
addN = () => this.setState({n: this.state.n + 1});
//constructor(){
this.addN = ()=> this.setState({n: this.state.n + 1})
}
上面两种写法等价
render(){
return <button onClick={this.addN}>n+1</button>
}
}
如果这样写的话:
addN(){
this.setState({n: this.state.n + 1})
}//addN: functioin(){
this.setState({n: this.state.n + 1})
}下面这种写法的addN在原型上,this可变成window,上面的写法在对象上,this不会变成window。
tips
所有的函数的this都是参数,由调用决定,所以可变
唯独箭头函数的this不变,箭头函数不接受this
this 的指向可参考我的博客 js函数中的this
如有错误,请留言指正!!!