jsx代码——>通过babel-loader——>转译成React.createElement()函数调用——>创建虚拟DOM(一个js对象)——>通过ReactDOM.render()将虚拟DOM渲染为DOM

  1. <body>
  2. <div id="root"></div>
  3. </body
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import App from './App';
  4. ReactDOM.render(
  5. <React.StrictMode>
  6. <App />
  7. </React.StrictMode>,
  8. document.getElementById('root')
  9. );
  1. import Y from "./class";
  2. import X from "./function";
  3. function App() {
  4. return (
  5. <>
  6. <X/>
  7. <Y/>
  8. </>
  9. )
  10. }
  11. export default App;

类组件

  1. import React from 'react';
  2. class Y extends React.Component{
  3. constructor(props){
  4. super(props)
  5. this.state={
  6. y:1,
  7. m:1,
  8. user:{
  9. name:"bruce",
  10. age:18
  11. }}
  12. }
  13. add1=()=>{this.setState((state)=>({y:state.y+10}),()=>{
  14. console.log(`我是setState完成后再执行的回调函数,此时的y是${this.state.y}`)
  15. })
  16. console.log(`因为setState是异步更新UI的,所以并不能立刻得到最新的y,此时的y仍然是${this.state.y}`)
  17. }
  18. add2=()=>{
  19. this.setState({y:this.state.y+1})
  20. this.setState({y:this.state.y+2})
  21. }
  22. add3=()=>{
  23. this.setState((state)=>({y:state.y+1}))
  24. this.setState((state)=>({y:state.y+2}))
  25. }
  26. change1=()=>{
  27. this.setState((state)=>({user:{age:10}}))
  28. }
  29. change2=()=>{
  30. this.setState((state)=>({user:{...state.user,age:10}}))
  31. }
  32. render(){
  33. console.log(`我在页面渲染时执行此时的y是${this.state.y}`)
  34. return(
  35. <>
  36. <div>我是类组件
  37. <div>y:{this.state.y}</div>
  38. <button onClick={this.add1}>函数+10</button>
  39. <button onClick={this.add2}>对象+1又+2</button>
  40. <button onClick={this.add3}>函数+1又+2</button>
  41. <div>m:{this.state.m}</div>
  42. <div>name:{this.state.user.name}</div>
  43. <div>age:{this.state.user.age}</div>
  44. <button onClick={this.change1}>不保留其余属性</button>
  45. <button onClick={this.change2}>保留其余属性</button>
  46. </div>
  47. </>
  48. )
  49. }
  50. }
  51. 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外面

数据单向流动:父组件中的数据无法被子组件修改

函数组件

  1. import React, { useState } from 'react'
  2. const X = props =>{
  3. const [x,setX]= useState(1)
  4. const [m,setM]= useState(10)
  5. console.log(x)
  6. return(
  7. <>
  8. <div>
  9. 我是函数组件
  10. <div>x:{x}</div>
  11. </div>
  12. <button onClick={()=>setX(x+1)}>+1</button>
  13. <div>m:{m}</div>
  14. <button onClick={()=>setM(m+1)}>+1</button>
  15. </>
  16. )
  17. }
  18. export default X

函数组件注意事项:

有多个state时,最好用多个useState来写,用对象形式写在一个useState里面的话,会在更改局部数据的时候导致其余数据变为undefined,函数组件不会自动合并第一层数据

数据单向流动:父组件中的数据无法被子组件修改