React高级
拓展:
ios、安卓、h5、小程序、app在移动端开发上有啥区别?
应用场景不同:
- 原生的native app开发,native需要客户端的发版才能做更新迭代
- 客户端嵌套页面webview 和 混合应用hybrid app开发 — 要做快的发版,更新迭代的话
- mini program - 小程序开发
高阶组件 HOC
hoc:higher order component
本身不是复杂的内容,也不是React官方提供,他是一种设计模式组成的高阶用法,接收一个组件作为参数并返回一个新的组件,React是用组件拼装页面的
简单来说,hoc是组件作为参数,返回值也是组件
HOC 主要用于代码复用,类似于Vue中的mixin
function HOC(WrappedComponent){
return props=><WrappedComponent {
...props} />
}
这里的props传递可以看作是 vue中的,this.$slots.defaults传递一样
//类的使用
function HOC(WrappedComponent){
return class extends React.Component{
constructor(props){
super(props)
}
render(){
const newProps={
name:"zhangsan"
}
return <WrappedComponent {
...props} {
...newProps} />
}
}
}
class类的完整示例:
import React from 'react';
// 创建 HOC,增强组件功能:withCounter 是我们定义的高阶组件,它接收一个组件(WrappedComponent)并返回一个新的组件。
function withCounter(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0 };
}
increment = () => {
this.setState(prevState => ({
count: prevState.count + 1 }));
};
render() {
return (
<WrappedComponent
{
...this.props}
count={
this.state.count} // 将新的 state(count)传递给原组件
increment={
this.increment} // 将新的方法(increment)传递给原组件
/>
);
}
};
}
// 创建一个基础组件,接收 count 和 increment 作为 props
function Counter({
count, increment }) {
return (
<div>
<p>Count: {
count}</p>
<button onClick={
increment}>Increment</button>
</div>
);
}
// 使用 HOC 包装 Counter 组件
const EnhancedCounter = withCounter(Counter);
// 使用增强后的组件
export default function App() {
return <EnhancedCounter />;
}
分类:
- 属性代理
- 反向继承
属性代理
返回的是原本的组件
- 代理props
function HOC(WrappedComponent){
const newProps = {
name:'zhangsan'
}
return props=><WrappedComponent {
...props} {
...newProps} />
}
- 模拟state
function HOC(WrappedComponent){
return class extends React.Component {
constructor(props){
super(props)
this.state = {
name:"zhangsan"
}
this.onChange = this.onChange.bind(this)
}
onChange=(e)=>{
this.setState({
name:e.target.value
})
}
render(){
const newProps={
name: {
value: this.state.name,
onChange:this.onChange
}
}
return <WrappedComponent {
...this.props} {
...newProps} />
}
}
}
function Demo(props) {
const {
name } = props
const {
value, onChange } = name;//props
// 定义新的state方法
}
// 在外部的组件中定义的state state:name,methods:onChange
// 传递给内部的 WrappedComponent,通过props的方式去传递给他,能够获取value和onChange事件,然后去消费它
- 条件渲染,基于返回组件做的自定义处理
function HOC(WrappedComponent) {
// custom
if (show = false) {
return <div>暂无数据</div>
}
return props=> <WrappedComponent {
...props} />
}
反向继承
使用类组件的方式
返回的是新的组件
function HOC(WrappedComponent) {
return class extends WrappedComponent{
render() {
return super.render();
}
}
}
这里,返回的新组件是原先的组件一比一复制过来的。
使用:
function HOC(WrappedComponent) {
// componentDidMount 新加功能
const didMount = WrappedComponent.prototype.componentDidMount;//原本组件的mount方法
return class extends WrappedComponent{
// constructor() { this.state=WrappedComponent.prototype.state}
componentDidMount() {
if (didMount) {
//需要将这样的生命周期关联的事件绑定到自定义的类中
didMount.bind(this) //新的组件里面,将原本组件生命周期方法执行了一遍
}
// handle custom 自定义逻辑
this.setState({
number:2
})
}
render() {
return super.render();
}
}
}
举例使用:
计算组件渲染时间:
function withTiming(WrappedComponent) {
return class extends WrappedComponent{
constructor(props) {
super(props);
start = 0;
end = 0;
}
componentWillMount() {
//继承链上的生命周期方法依次执行,由子到父的顺序执行,也就是说,先执行 withTiming 中的 componentWillMount,然后执行 WrappedComponent 中的 componentWillMount