jsx代码——>通过babel-loader——>转译成React.createElement()函数调用——>创建虚拟DOM(一个js对象)——>通过ReactDOM.render()将虚拟DOM渲染为DOM
<body>
<div id="root"></div>
</body
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
import Y from "./class";
import X from "./function";
function App() {
return (
<>
<X/>
<Y/>
</>
)
}
export default App;
类组件
import React from 'react';
class Y extends React.Component{
constructor(props){
super(props)
this.state={
y:1,
m:1,
user:{
name:"bruce",
age:18
}}
}
add1=()=>{this.setState((state)=>({y:state.y+10}),()=>{
console.log(`我是setState完成后再执行的回调函数,此时的y是${this.state.y}`)
})
console.log(`因为setState是异步更新UI的,所以并不能立刻得到最新的y,此时的y仍然是${this.state.y}`)
}
add2=()=>{
this.setState({y:this.state.y+1})
this.setState({y:this.state.y+2})
}
add3=()=>{
this.setState((state)=>({y:state.y+1}))
this.setState((state)=>({y:state.y+2}))
}
change1=()=>{
this.setState((state)=>({user:{age:10}}))
}
change2=()=>{
this.setState((state)=>({user:{...state.user,age:10}}))
}
render(){
console.log(`我在页面渲染时执行此时的y是${this.state.y}`)
return(
<>
<div>我是类组件
<div>y:{this.state.y}</div>
<button onClick={this.add1}>函数+10</button>
<button onClick={this.add2}>对象+1又+2</button>
<button onClick={this.add3}>函数+1又+2</button>
<div>m:{this.state.m}</div>
<div>name:{this.state.user.name}</div>
<div>age:{this.state.user.age}</div>
<button onClick={this.change1}>不保留其余属性</button>
<button onClick={this.change2}>保留其余属性</button>
</div>
</>
)
}
}
export default Y
类组件注意事项:
super(props)要在其他语句前调用
this.state初始赋值只能在构造函数中使用
不能直接修改this.state,应使用setState
在 React.Component
的子类中有个必须定义的 render()
函数
render应该为纯函数,与浏览器交互的操作都应放在componentDidMount()
或其他生命周期方法中执行
setState中用对象,连续执行+1和+2操作,最终只会得到+2的变化;因为setState是异步更新UI的,对象的取值在声明时就已经确定,此时的this.state.y仍然是旧值
改成函数形式就可以解决这个问题,函数中变量的取值要在调用时才能确定,+2函数操作调用时,+1操作已完成,this.state.y值已经是最新的了
类组件中改变state第一层中的局部数据,其余数据会自动合并,但第一层以后的数据做局部修改,同层的其他数据就会变为undefined,想要保留需要用…展开操作符
事件对应的操作函数,最好以箭头函数的形式,写在constructor外面
函数组件
import React, { useState } from 'react'
const X = props =>{
const [x,setX]= useState(1)
const [m,setM]= useState(10)
console.log(x)
return(
<>
<div>
我是函数组件
<div>x:{x}</div>
</div>
<button onClick={()=>setX(x+1)}>+1</button>
<div>m:{m}</div>
<button onClick={()=>setM(m+1)}>+1</button>
</>
)
}
export default X
函数组件注意事项:
有多个state时,最好用多个useState来写,用对象形式写在一个useState里面的话,会在更改局部数据的时候导致其余数据变为undefined,函数组件不会自动合并第一层数据
数据单向流动:父组件中的数据无法被子组件修改