在日常开发中,能够优雅的复用组件和逻辑,是优秀开发者的职责。在react中,复用逻辑的方式有很多,可以适用于不同的业务场景。今天说三个比较有代表性的,Render Props、HOC、Hooks

Render Props

创建一个接受函数作为其子组件的prop的组件,该函数返回一个React元素。通过这种方式,父组件可以通过传递不同的函数来重用相同的逻辑。

示例代码:

function DataFetcher({ url, children }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => setData(data))
      .catch(error => console.error('Error fetching data: ', error));
  }, [url]);

  return children(data);
}

function DisplayData() {
  return (
    <DataFetcher url="https://api.example.com/data">
      {data => (
        <div>
          {data ? (
            <ul>
              {data.map(item => (
                <li key={item.id}>{item.name}</li>
              ))}
            </ul>
          ) : (
            <p>Loading...</p>
          )}
        </div>
      )}
    </DataFetcher>
  );
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

在上面的例子中,DataFetcher组件通过children prop接受一个函数,并将获取到的数据作为参数传递给该函数,DisplayData组件通过传递一个函数来获取并渲染数据。

Higher-Order Components (HOC) 高阶函数

高阶组件是一个函数,接受一个组件作为参数并返回一个新的增强组件。

示例代码:

function withDataFetching(WrappedComponent, url) {
  return function DataFetchingComponent(props) {
    const [data, setData] = useState(null);

    useEffect(() => {
      fetch(url)
        .then(response => response.json())
        .then(data => setData(data))
        .catch(error => console.error('Error fetching data: ', error));
    }, [url]);

    return <WrappedComponent {...props} data={data} />;
  };
}

function DisplayData({ data }) {
  return (
    <div>
      {data ? (
        <ul>
          {data.map(item => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

const DisplayDataWithFetching = withDataFetching(DisplayData, 'https://api.example.com/data');
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

在上面的例子中,withDataFetching函数接受一个组件和一个URL作为参数,并返回一个新的组件,在新组件内部进行数据获取并传递给被包裹的组件。

Hooks

自定义Hooks允许你在函数组件中重用状态逻辑。通过将逻辑封装在自定义Hook中,可以在不同的组件中复用它。

示例代码:

function useDataFetching(url) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => setData(data))
      .catch(error => console.error('Error fetching data: ', error));
  }, [url]);

  return data;
}

function DisplayData() {
  const data = useDataFetching('https://api.example.com/data');

  return (
    <div>
      {data ? (
        <ul>
          {data.map(item => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.

在上面的例子中,useDataFetching自定义Hook封装了数据获取逻辑,DisplayData组件通过调用该Hook获取数据并渲染。

这些方法提供了灵活的方式来在React中实现逻辑复用,具体选择取决于项目中具体的业务场景和开发团队的偏好。