尝试用一个简单的例子来说明HOC(Higher Order Component)
HOC的含义是什么?
高级组件是一个函数,它获取组件并返回一个新组件。
简单的例子
以下是一个逻辑,它会在加载3秒钟之后才加载组件。
从逻辑中可以看出的共同部分是:
1.加载3秒钟
2.加载完成后加载组件
通过使用高阶组件(HOC),可以将这些共同部分提取出来以便进行复用。
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function Button() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <button>Button</button>;
}
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function Input() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <input defaultValue={"Input"} />;
}
下面是引入HOC的示例!
import React, { useState } from 'react'
import { useEffect } from 'react';
import withLoading from './withLoading';
function Button() {
return <button>Button</button>
}
export default withLoading(Button); // HOCからcomponentをリターンしてもらう
import React, { useState } from 'react'
import { useEffect } from 'react';
import withLoading from './withLoading';
export default function Input() {
return <input defaultValue={"Input"} />;
}
export default withLoading(Input); // HOCからcomponentをリターンしてもらう
在Button组件和Input组件中,所有共同的逻辑都被省略掉了。
取而代之的是,增加了调用HOC(高阶组件)的逻辑。
正如之前所说,HOC将组件作为参数传递,并返回一个组件,
所以我们将其写成export default {HOC组件(组件)}。
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function withLoading(Compomnent) {
const WithLoadingComponent = (props) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <Compomnent {...props}/>;
}
return WithLoadngComponent;
}
HOC是指高阶组件。从逻辑上理解,高阶组件不会修改作为参数传入的组件。
你可以使用接收到的组件进行封装,并通过接收到的组件的每个props进行渲染。此外,高阶组件也可以是没有副作用的纯函数(为什么withLoading以小写字母开头!)。它在纯函数中创建并返回组件的结构。
HOC的命名规则是使用〜〜。