Я хочу отобразить свой функциональный компонент "Домой" после того, как я получу Данные из функции ...
Затем вы должны получить данные из getbannerdata
в родительском компоненте, и передать его HomeScreen
в качестве реквизита. В HomeScreen
вы ничего не можете сделать, чтобы предотвратить рендеринг компонента до прибытия данных из getbannerdata
.
В целом, с компонентами у вас есть два варианта, когда нужно получить асинхронный процесс c их содержание:
Сделайте это в компоненте и выполните рендеринг в случае, когда у компонента еще нет данных (возможно, с сообщением «загрузка» или аналогичным).
Не создавайте компонент, пока у вас нет данных, что означает выполнение его в родительском элементе.
Пример # 1:
const { useState, useEffect } = React;
function getbannerdata() {
return new Promise(resolve => {
setTimeout(resolve, 800, "This is the banner");
});
}
const HomeScreen = () => {
const [banner, setBanner] = useState(null);
useEffect(() => {
getbannerdata().then(banner => setBanner(banner));
}, [banner]);
return (
<div className="boxed">
This is <code>HomeScreen</code>
{banner && <div className="boxed">{banner}</div>}
</div>
);
};
const App = () => {
return (
<div className="boxed">
This is <code>App</code>
<HomeScreen />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
.boxed {
border: 1px solid black;
padding: 4px;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
или с индикатором «загрузки»:
const { useState, useEffect } = React;
function getbannerdata() {
return new Promise(resolve => {
setTimeout(resolve, 800, "This is the banner");
});
}
const HomeScreen = () => {
const [banner, setBanner] = useState(null);
useEffect(() => {
getbannerdata().then(banner => setBanner(banner));
}, [banner]);
return (
<div className="boxed">
This is <code>HomeScreen</code>
<div className="boxed">{banner ? banner : <em>Loading...</em>}</div>
</div>
);
};
const App = () => {
return (
<div className="boxed">
This is <code>App</code>
<HomeScreen />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
.boxed {
border: 1px solid black;
padding: 4px;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Пример # 2:
const { useState, useEffect } = React;
function getbannerdata() {
return new Promise(resolve => {
setTimeout(resolve, 800, "This is the banner");
});
}
const HomeScreen = ({banner}) => {
return (
<div className="boxed">
This is <code>HomeScreen</code>
<div className="boxed">{banner}</div>
</div>
);
};
const App = () => {
const [banner, setBanner] = useState(null);
useEffect(() => {
getbannerdata().then(banner => setBanner(banner));
}, [banner]);
return (
<div className="boxed">
This is <code>App</code>
{banner && <HomeScreen banner={banner} />}
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
.boxed {
border: 1px solid black;
padding: 4px;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Я нашел эту статью Дана Абрамова очень полезной. Якобы речь идет о useEffect
, но на самом деле речь идет о жизненном цикле функциональных компонентов и о ловушках в целом.