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 中。