繁体   English   中英

将元素从子组件移动到其父组件

[英]Move element from child component to its parent

我想设计一个 ApiFetcher 以防止重复代码。

如何将自定义子组件传递给我的 ApiFetcher,以便它呈现我在自定义组件中指定的内容,而不是返回语句中的硬编码元素?

我想将 ApiFetcher 和 CompanyProfile 组件的逻辑保留在其父组件之外。

import React from "react";
import ReactDOM from "react-dom";
import { useState, useEffect } from "react";

function ApiFetcher(props) {
  const apiUrl =
    "https://financialmodelingprep.com/api/v3/profile/AAPL?apikey=demo";

  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetch(apiUrl)
      .then((res) => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      );
  }, []);

  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    // TODO: move the following <div> out of this component and render children
    return (
      <div>
        {items.map((item) => (
          <li key={item.symbol}>
            {item.companyName} {item.price}
          </li>
        ))}
      </div>
    );
  }
}

function CompanyProfile() {
  return (
    <div>
      <ApiFetcher>
        {/*
        TODO: move the following into this component:

      <div>
        {items.map((item) => (
          <li key={item.symbol}>
            {item.companyName} {item.price}
          </li>
        ))}
      </div>
    */}
      </ApiFetcher>
    </div>
  );
}

ReactDOM.render(<CompanyProfile />, document.getElementById("root"));

您可以使用props.children将渲染逻辑移动到父组件。 以下是我将如何构建组件:

function ApiFetcher({url}) {
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetch(url)
      .then((res) => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      );
  }, []);

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  if (!isLoaded) {
    return <div>Loading...</div>;
  }

  return props.children({response: items});
}

用法

<ApiFetcher>
{({response}) => // Rendering logic}
</ApiFetcher>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM