Как использовать useState внутри реагирующего функционального компонента, который является асинхронным - PullRequest
0 голосов
/ 02 марта 2020

My App - это функциональный компонент, который объявлен async, потому что мне нужно извлечь данные с сервера до того, как представление будет обработано, и код выглядит следующим образом:

import React,{useState} from  "react";
import DashBoard from './components/DashBoard'
const axios = require('axios')


const App = async props => {
  const allDashBoardsList = await axios.get('http://localhost:9000/getAllDashBoardNames')
  const [dashboard,setDashboard] = useState(allDashBoardsList.data[0].dashboard)
  const handleDashboardChange = e => {
    setDashboard(e.target.value)
  }
   return (
    <>
      <select>
        {allDashBoardsList.data.map(e => <option value={e.dashboard} onChange  = {handleDashboardChange} > {e.dashboard} </option>)}
      </select>
      <DashBoard dashboard={dashboard} />
    </>
   )
 }



export default App

и мой индекс. js вот так,

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
App().then(e => {
    ReactDOM.render(e, document.getElementById('root'));
})

Все работает без ошибок, когда я возвращаю <h1> Hello </h1> из App, но я получаю

Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component

при использовании useState чтобы установить состояние

есть ли способ противостоять этому или мне нужно использовать class component с UNSAFE_componentWillMount

1 Ответ

2 голосов
/ 02 марта 2020

Попробуйте вместо этого обернуть ваш асин c вызов в ловушку useEffect и установить приемлемое состояние по умолчанию

const App = props => {
  const [dashboard,setDashboard] = useState('placeholder default state');

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios.get('http://localhost:9000/getAllDashBoardNames');
      setDashboard(allDashBoardsList.data[0].dashboard);
    };
    fetchData();
  }, []);

  const handleDashboardChange = e => {
    setDashboard(e.target.value)
  }
   return (
    <>
      <select>
        {allDashBoardsList.data.map(e => <option value={e.dashboard} onChange  = {handleDashboardChange} > {e.dashboard} </option>)}
      </select>
      <DashBoard dashboard={dashboard} />
    </>
   )
 }
...