React.js 中的高阶组件(HOC)是一个非常有用的编程技术,它可以让你创建一个函数,将一个组件作为参数并返回一个新的包装组件。
这个技术背后的思想是将常用的逻辑和状态抽象出来,以便以后可以重用。如果你想在多个组件中共享某些代码或行为,那么 HOC 是一个理想的选择。
下面是一个简单的例子,在这个例子中,我们创建了一个名为 withData 的高阶组件,它用来 fetch 一个指定数据源并将数据传递给包装组件。
import React, { Component } from "react";
const withData = (url) => (WrappedComponent) => {
return class extends Component {
constructor(props) {
super(props);
this.state = {
data: null,
isLoading: false,
error: null,
};
}
componentDidMount() {
this.setState({ isLoading: true });
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then((data) => {
this.setState({ data, isLoading: false });
})
.catch((error) => {
this.setState({ error, isLoading: false });
});
}
render() {
const { isLoading, data, error } = this.state;
return (
<WrappedComponent
isLoading={isLoading}
data={data}
error={error}
{...this.props}
/>
);
}
};
};
export default withData;如你所见,withData 函数非常普通,这是一个高阶函数,它返回一个新的函数,该函数使用一个新类包装输入组件。该类具有状态和方法,用于获取和存储异步数据,并将其传递给包装组件。
现在,我们可以使用 withData 函数来创建一个包装组件,例如:
import withData from "./withData";
const UserList = ({ isLoading, data, error }) => {
if (isLoading) {
return <p>Loading users...</p>;
}
if (error) {
return <p>Error loading users: {error.message}</p>;
}
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
const UserListWithData = withData(
"https://jsonplaceholder.typicode.com/users"
)(UserList);
export default UserListWithData;在这里,我们定义了一个 UserList 组件,该组件渲染一个用户列表,它需要异步获取数据。然后,我们使用 withData 函数来创建 UserListWithData 包装组件,该组件使用 withData 的 fetch 功能获取数据并将其传递给原始 UserList 组件。
高阶组件是一个使用 React.js 的复杂应用程序时的核心方案。如果你在多个组件中发现自己编写了相同的逻辑代码,请考虑将其提取到可重用的 HOC 中。