Как я могу гарантировать, что ответ axios get выполняется только один раз, а также доступен при передаче данных дочернему компоненту?

#javascript #reactjs #debugging #react-hooks

#язык JavaScript #реагирует на #отладка #реагируют-крючки

Вопрос:

Всякий раз, когда я отправлял uploadsData переменную App.js в lt;Gallery data={uploadsData}/gt;} /gt; компонент через опору, она вызывалась более одного раза. Первый массив ничего не содержит, но следующие два массива содержат правильные данные.

Кроме того, всякий раз, когда я навожу курсор на синий ! , я получаю это предупреждение, показанное на скриншоте. Это означает, что я никогда не смогу правильно получить доступ к этому объекту должным образом.

Как я могу сделать так, чтобы он выполнялся один и только один раз, чтобы я мог получить доступ к объекту надлежащим образом?

Я думал, что наличие [] in useEffect() (2-й параметр) в качестве зависимости приведет к тому, что это будет выполнено только один раз?

Заранее спасибо, что нашли время для чтения. Я открыт для любых отзывов, включая улучшения/изменения кода, которые считаются лучшей практикой

Вот App.js :

 import { useEffect, useState } from 'react'; import { BrowserRouter as Router, Switch, Route, useHistory} from 'react-router-dom'; import ReactDOM from 'react-dom'; import '../../sass/HomePage/homePage.scss'; import LoginRegister from "./LoginRegister/LoginRegister"; import Gallery from "./Gallery/Gallery"; import Cookies from 'js-cookie';  const App = () =gt; {  const [uploadsData, setUploadsData] = useState([]);  let { push } = useHistory();  let authToken = Cookies.get('token');   useEffect(() =gt; {  getUploads();  },[]);   function getUploads() {  const headers = {  "Accept": 'application/json',  "Authorization": `Bearer ${authToken}`  }   axios.get('http://localhost:8005/api/get-uploads', {headers})  .then(resp =gt; {  let uData = [...uploadsData,resp];  setUploadsData(uData);  if (authToken !== null) {  push('/gallery');  } else {  console.log("User's NOT authenticated, returning to login view");  push('/');  }  }).catch(error =gt; {  console.log(error);  })  }   return (  lt;gt;  lt;Switchgt;  lt;Route exact path="/" component={LoginRegister} /gt;  lt;Route component={() =gt; lt;Gallery data={uploadsData}/gt;} /gt;  lt;/Switchgt;  lt;/gt;  ); }  export default App;  if (document.getElementById('example')) {  ReactDOM.render(lt;Routergt;lt;App/gt;lt;/Routergt;, document.getElementById('example')); }  

Вот Gallery.js :

 import React from 'react';  const Gallery = (data) =gt; {   return (  lt;gt;   {console.log(data)}  lt;/gt;  ); }  export default Gallery;  

Ответ №1:

Показывать компонент при подготовке данных:

 import { useEffect, useState } from 'react'; import { BrowserRouter as Router, Switch, Route, useHistory} from 'react-router-dom'; import ReactDOM from 'react-dom'; import '../../sass/HomePage/homePage.scss'; import LoginRegister from "./LoginRegister/LoginRegister"; import Gallery from "./Gallery/Gallery"; import Cookies from 'js-cookie';  const App = () =gt; {  const [uploadsData, setUploadsData] = useState([]);  let { push } = useHistory();  let authToken = Cookies.get('token');   useEffect(() =gt; {  getUploads();  },[]);   function getUploads() {  const headers = {  "Accept": 'application/json',  "Authorization": `Bearer ${authToken}`  }   axios.get('http://localhost:8005/api/get-uploads', {headers})  .then(resp =gt; {  let uData = [...uploadsData,resp];  setUploadsData(uData);  if (authToken !== null) {  push('/gallery');  } else {  console.log("User's NOT authenticated, returning to login view");  push('/');  }  }).catch(error =gt; {  console.log(error);  })  }   return (  lt;gt;  lt;Switchgt;  lt;Route exact path="/" component={LoginRegister} /gt;  lt;Route component={() =gt; lt;gt; {uploadsData?.data?.length amp;amp; lt;Gallery data={uploadsData}/gt; }lt;/gt;} /gt;  lt;/Switchgt;  lt;/gt;  ); }  export default App;  if (document.getElementById('example')) {  ReactDOM.render(lt;Routergt;lt;App/gt;lt;/Routergt;, document.getElementById('example')); }  

И используйте памятку, чтобы избежать повторного использования компонента, когда в реквизитах нет изменений:

 import React, {memo} from 'react';  const Gallery = (data) =gt; {   return (  lt;gt;   {console.log(data)}  lt;/gt;  ); }  export default memo(Gallery);  

Комментарии:

1. Это кажется интересным решением, но когда я попробовал его — он выдал мне пустую страницу без ошибок, отображаемых в консоли. Я пытаюсь понять, почему.