class类组件特性
context和contextType
- context:实现跨层级组件数据传递
- contextType: 类静态属性,可以不必使用函数就可以消费数据 ```javascript // 创建context上下文提供者 const BatteryContext = createContext();
// 中间的组件
class Middle extends React.Component {
render() {
return (
context:{x}
} ) } } class App extends React.Component { state = { battery: 20, }; render() { const { battery } = this.state; return (
```javascript// 创建context上下文提供者const BatteryContext = createContext();// 中间的组件class Middle extends React.Component {render() {return <Leaf />;}}class Leaf extends React.Component {// 消费数据时更加方便,不必使用函数// 相当于对上下文提供者 BatteryContext,做了数据接收static contextType = BatteryContext;render() {const battery = this.context;return <h1>context:{battery}</h1>;}}class App extends React.Component {state = {battery: 20,onLine: false,};render() {const { battery, onLine } = this.state;return (<BatteryContext.Provider value={battery}>{/* battery 动态变化 */}<button onClick={() => this.setState({ battery: battery + 1 })}>add</button><Middle /></BatteryContext.Provider>);}}
lazy和Suspense
- lazy: 引入组件时,进行懒加载
- Suspense:在懒加载组件期间,页面内容显示的处理
```javascript import React from “react”;const About = lazy(() => import("./About.js"));class App extends React.Component {render() {return (<div>{/* lazy生成的组件,必须配合 Suspense使用,否则会报错 */}<Suspense fallback={<div>loading</div>}><About></About></Suspense></div>);}}
export default class About extends React.Component { render() { return
about
;
}
}
<a name="I4tb2"></a>### memo- React.memo 可以对组件进行缓存。进行性能优化;有点类似shouldUpdateComponent或PureComponent的作用。<a name="TgCMo"></a>#### 类组件shouldUpdateComponent的使用```javascriptclass Foo extends React.Component {shouldComponentUpdate(nextProps, nextState) {if (nextProps.name === this.props.name) {// 属性相同,不进行渲染return false;}// 否则进行渲染return true;}render() {console.log("render");return <div>Foo</div>;}}class App extends React.Component {state = {count: 0,};render() {const { count } = this.state;return (<div><button onClick={() => this.setState({ count: count + 1 })}>add</button><Foo name="foo"></Foo></div>);}}
PureComponent的使用
// 只是进行浅比较class Foo extends PureComponent {render() {console.log("render");return <div>Foo</div>;}}
React.memo的使用
function Foo() {console.log("render");return <div>Foo</div>;}const MemoFoo = React.memo(Foo)class App extends React.Component {state = {count: 0,};render() {const { count } = this.state;return (<div><button onClick={() => this.setState({ count: count + 1 })}>add</button><MemoFoo name="foo"></MemoFoo></div>);}}
hooks特性
类组件的不足
hooks的出现,是为了解决类组件中存在的问题,主要有:
- 状态逻辑难复用
- this的使用问题
- 生命周期函数混杂着难以处理的逻辑
为了实现类组件属性的复用,有渲染属性和高阶组件
class Resizable extends React.Component {state = {size: [window.innerWidth, window.innerHeight],};onSize = () => {this.setState({ size: [window.innerWidth, window.innerHeight] });};componentDidMount() {window.addEventListener("resize", this.onSize);}componentWillUnmount() {window.removeEventListener("resize", this.onSize);}render() {// 为了解决属性复用,return this.props.render(this.props.size);}}class Foo extends React.Component {render() {const [width, height] = this.props.size;return (<div>{width} X {height}</div>);}}// 使用类组件,渲染属性<Resizable render={(size) => <Foo size={size} />} />;
// 高阶组件function resizable(Child) {return class Wrapper extends React.Component {state = {size: [window.innerWidth, window.innerHeight],};onSize = () => {this.setState({ size: [window.innerWidth, window.innerHeight] });};componentDidMount() {window.addEventListener("resize", this.onSize);}componentWillUnmount() {window.removeEventListener("resize", this.onSize);}render() {// 为了解决属性复用const size = this.props.size;return <Child size={size} />;}};}class Foo extends React.Component {render() {const [width, height] = this.props.size;return (<div>{width} X {height}</div>);}}// 包装成高阶组件const WrapperFoo = resizable(Foo);// 使用高阶组件<WrapperFoo />
hooks逻辑复用
function HookResize() {const size = useSize();useEffect(() => {document.title = size.join("x");});return (<div>{size[0]}x{size[1]}</div>);}function useSize() {const [size, setSize] = useState([window.innerWidth, window.innerHeight]);const onResize = () => {setSize([window.innerWidth, window.innerHeight]);};useEffect(() => {window.addEventListener("resize", onResize);return () => {window.removeEventListener("resize", onResize);};});return size;}
hooks的优势
- 函数组件hooks无this问题
- 自定义hook方便复用状态逻辑
- 副作用的关注点分离
