[英]Move element from child component to its parent
I want to design an ApiFetcher in order to prevent duplicate code.我想设计一个 ApiFetcher 以防止重复代码。
How to I pass a custom child component to my ApiFetcher so that it renders the content I specify in the custom component instead of a hard coded element in the return statement?如何将自定义子组件传递给我的 ApiFetcher,以便它呈现我在自定义组件中指定的内容,而不是返回语句中的硬编码元素?
I want to keep the logic of the ApiFetcher and the CompanyProfile components out of their parent components.我想将 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"));
You can maybe use props.children
in order to move rendering logic to Parent component.您可以使用
props.children
将渲染逻辑移动到父组件。 Here's how I will strucutre the component:以下是我将如何构建组件:
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});
}
Usage用法
<ApiFetcher>
{({response}) => // Rendering logic}
</ApiFetcher>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.