一、类组件 setState 的 2 种写法
1、对象式 setState
js
setState(stateChange, [callback])
-
stateChange 为状态改变对象,该对象可以体现出状态的更改
-
callback 是可选的回调函数,它在状态更新完毕、界面也更新后(render 函数调用后)才被调用
js
this.setState({
count: this.state.count + 1,
});
js
this.setState(
{
count: this.state.count + 1,
},
() => {
console.log("更新后的 count:", this.state.count);
},
);
2、函数式 setState
js
setState(updater, [callback])
-
updater 为返回 stateChange 对象的函数,updater 可以接收到 prevState 和 props 参数
-
callback 是可选的回调函数,它在状态更新完毕、界面也更新后(render 函数调用后)才被调用
js
this.setState((prevState, props) => ({
count: prevState.count + 1,
}));
js
this.setState(
(prevState, props) => ({
count: prevState.count + 1,
}),
() => {
console.log("更新后的 count:", this.state.count);
},
);
3、注意事项
- 如果新状态不依赖于原状态,使用对象式 setState;如果新状态依赖于原状态,使用函数式 setState
jsx
// 最终 count 为 1,两次都基于旧的 this.state.count 计算
import { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
add = () => {
this.setState({
count: this.state.count + 1,
});
this.setState({
count: this.state.count + 1,
});
};
render() {
return (
<div>
<h3>{this.state.count}</h3>
<button onClick={this.add}>Add</button>
</div>
);
}
}
jsx
// 最终 count 为 2,每次都基于上次的 this.state.count 计算
import { Component } from "react";
export default class App extends Component {
state = {
count: 0,
};
add = () => {
this.setState((prevState, props) => ({
count: prevState.count + 1,
}));
this.setState((prevState, props) => ({
count: prevState.count + 1,
}));
};
render() {
return (
<div>
<h3>{this.state.count}</h3>
<button onClick={this.add}>Add</button>
</div>
);
}
}
- 如果需要在 setState 执行后获取最新的状态数据, 要在 callback 中读取
jsx
this.setState({
count: this.state.count + 1,
});
console.log(this.state.count);
// 输出结果为 0
jsx
add = () => {
this.setState((prevState, props) => ({
count: prevState.count + 1,
}));
console.log(this.state.count);
// 输出结果为 0
};
二、LazyLoad
1、基本介绍
-
通过 lazy 函数配合 import 函数动态加载路由组件,路由组件代码会被分开打包
-
通过
<Suspense>指定,在加载得到路由打包文件前,显示一个自定义加载界面
2、演示
(1)page
- About 页面
jsx
import { Component } from "react";
export default class About extends Component {
render() {
return <h2>About</h2>;
}
}
- Home 页面
jsx
import { Component } from "react";
export default class Home extends Component {
render() {
return <h2>Home</h2>;
}
}
- Loading 页面
jsx
import { Component } from "react";
export default class Loading extends Component {
render() {
return (
<div>
<h1 style={{ backgroundColor: "gray", color: "orange" }}>Loading...</h1>
</div>
);
}
}
(2)main
- App 组件
jsx
import { Component, lazy, Suspense } from "react";
import { NavLink, Route } from "react-router-dom";
import Loading from "./pages/Loading";
import "./App.css";
const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));
export default class App extends Component {
render() {
return (
<div>
<div>
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
</div>
<div>
<Suspense fallback={<Loading />}>
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
</Suspense>
</div>
</div>
);
}
}
css
.active {
color: red;
}
- index.js
js
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root"),
);
3、打包影响
- 使用 LazyLoad 后的打包

- 不使用 LazyLoad 后的打包

三、useState
1、基本介绍
- useState 让函数式组件也可以有 state,并进行 state 数据的读写操作
js
const [xxx, setXxx] = useState(initValue)
-
initValue:第一次初始化指定的值在内部作缓存 -
[xxx, setXxx]:包含 2 个元素的数组,第 1 个为内部当前状态值,第 2 个为更新状态值的函数
setXxx的 2 种写法
-
setXxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值 -
setXxx(value => newValue):参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值
2、基本使用
jsx
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
const add = () => {
setCount(count + 1);
};
return (
<div>
<h3>{count}</h3>
<button onClick={add}>Add</button>
</div>
);
}
3、注意事项
- 如果新状态不依赖于原状态,
setXxx使用参数为非函数值;如果新状态依赖于原状态,setXxx使用参数为函数
jsx
// 最终 count 为 1,两次都基于旧的 count 计算
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
const add = () => {
setCount(count + 1);
setCount(count + 1);
};
return (
<div>
<h3>{count}</h3>
<button onClick={add}>Add</button>
</div>
);
}
jsx
// 最终 count 为 2,每次都基于上次的 count 计算
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
const add = () => {
setCount((prevCount) => prevCount + 1);
setCount((prevCount) => prevCount + 1);
};
return (
<div>
<h3>{count}</h3>
<button onClick={add}>Add</button>
</div>
);
}