const div = React.createElement('div', null) 是一个元素
const Div = () => React.createElement('div', null)是一个组件(就是一个回调),首字母大写
在 React 中,HTML
等标签会被翻译成 React.creatElement(‘div’)函数组件
function Hello(props) {return <h1> Hi, {props.name} </h1>}// 使用 <Hello name="Dudu" />
类组件
class Hello extends React.Component {constructor() {super()this.state = {n: 0}}render() {return <h1> Hi, {this.props.name} </h1>}}// 使用 <Hello name="Dudu" />
内部数据 state
类组件:用 this.state.n 读,用 this.setState({n: this.state.n+1}) 写(异步更新 )
函数组件:[n, setN] = useState(0),n 为数据,setN 为设置函数,0 为 n 的初始值
import React from 'react';import ReactDOM from 'react-dom';import './style.css';function App() {return (<div className='father'>father<Son /></div>);}class Son extends React.Component {constructor() {super();this.state = { n: 0 };}add() {// 不能直接 this.state.n += 1,react 不监听数据// this.setState({ n: this.state.n + 1 }); // 产生一个新对象// 由于 this.setState 为异步更新,若要实实时打印n,一般使用函数this.setSate((state) => {const n = state.n + 1;console.log(n);return {n};})}render() {return (<div className='son'>Son n: {this.state.n}<button onClick={() => {this.add()}}> +1 </button><Grandson /></div>);}}const Grandson = () => {// n 的初始值为0,setN 不改变 n ,setN 后得到一个新的 nconst [n ,setN] = React.useState(0);return (<div className='grandson'>Grandson n: {n}<button onClick={() => setN(n + 1)}>+1</button></div>);}const root = document.querySelector('#root');ReactDOM.render(<App />, root);
多个 state 数据的情况
以下为个人理解,极大可能理解错误,待考证
有多个 state 数据时,React 将新旧虚拟DOM 不一致的部分包括其子组件一起重渲染,对于没有变化的数据,渲染时只会保留栈内存中的数据,而不保留堆内存中的数据(因为栈内存中的地址改变了,React 会重新创建一个对象,对象中没有改动的数据不在这个新对象中,就会变成 undefined)
也就是说,React 局部重渲染的是新旧虚拟DOM表示的DOM中数据的栈内存中不一致的数据
具体原理看 useState 原理
- 数据在栈内存时:
 
类组件:
class MyCompnent extends React.Component {constructor() {super();this.state = {n: 0,m: 0}}addN() {// 改变 n 的值,重渲染后 m 的值不变this.setState({ n: this.state.n + 1 });}addM() {// 改变 m 的值,重渲染后 n 的值不变this.setState({ m: this.state.m + 1 });}}
函数组件
const MyComponent = () => {const [n, setN] = React.useState(0);const [m, setM] = React.useState(0);// 改变 n 的值,重渲染后 m 的值不变// 改变 m 的值,重渲染后 n 的值不变return (<div>n: {n} <button onClick={() => setN(n + 1)}></button>m: {m} <button onClick={() => setN(m + 1)}></button></div>)}
- 栈内存中为地址,数据在堆内存时
 
类组件
class MyCompnent extends React.Component {constructor() {super();this.state = {num: {n: 0,m: 0}}}addN() {// 改变 n 的值,重渲染后 m 的值变为 undefinedthis.setState({num: {n: 0}});}addM() {// 改变 m 的值,重渲染后 n 的值变为 undefinedthis.setState({num: {m: 0}});}}
函数组件:
const MyComponent = () => {const [state, setState] = React.useState({n:0, m:0});// 改变 n 的值,重渲染后 m 的值变为 undefined// 改变 m 的值,重渲染后 n 的值变为 undefinedreturn (<div>n: {state.n} <button onClick={() => setState({n: state.n + 1})}></button>m: {state.m} <button onClick={() => setState({m: state.m + 1})}></button></div>)}
解决方法:使用 ‘…’ 操作符号
// 类组件addN() {this.setState({...this.state.num,num: {n: 0}});}// 函数组件<button onClick={() => setState({...state, n: state.n + 1})}></button>
外部数据 props
类组件:用 this.props.n 读
函数组件:直接读取传入参数 props.n
传 props 属性用 “” 或 {}
import React from 'react';import ReactDOM from 'react-dom';import './style.css';function App() {return (<div className='father'>father{/* <Son messageForSon={1 + 1} /> */}<Son messageForSon="Hi, my son!" /></div>);}// 类组件class Son extends React.Component {render() {return (<div className='son'>Father to Son: {this.props.messageForSon}<Grandson massageForGrandson="Hi, son!" /></div>);}}// 函数组件const Grandson = (props) => {return (<div className='grandson'>Father to Son: {props.massageForGrandson}</div>);}const root = document.querySelector('#root');ReactDOM.render(<App />, root);

