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,函数组件不会自动合并第一层数据
数据单向流动:父组件中的数据无法被子组件修改
