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的使用
```javascript
class 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方便复用状态逻辑
- 副作用的关注点分离